All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-05-23 10:47 ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

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.

This v10 still has some un-answered comments and TODOs for v11.

This has been tested sucessfully on a 5.18-next based "vendor branch".

There's a missing dependency in the mediatek clock framework to allow a
mux clock to change it's parent automatically on rate change.
Without this change, the dpi driver won't properly set the clocks on
mode change and thus nothing will be displayed on screen.

Changes from v9:
- The DP-Phy is back to being a child device of the DP driver (as in v8)
- hot plug detection has been added back to Embedded Display Port... as
  after discussing with mediatek experts, this is needed eventhough the
  Embedded Display port is not un-pluggable
- rebased on linux-next
- simplified/split train_handler function, as suggested by Rex
- added comments on the sleep/delays present in the code
- removed previous patch introducing retries when receiving AUX_DEFER as
  this is already handled in the dp_aux framework
- added max-lane and max-linkrate device tree u8 properties instead of
  hardcoded #defines

Things that are in my todolist for v11:
- retrieve CK/DE support from panel driver instead of hardcoding it into
  the dpi driver
- refcount the dp driver "enabled" status for "future proofing"
- review the drm_dp_helpers for features/functions that have been
  re-implemented in the mediatek dp drivers

Older revisions:
RFC - https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
v1  - https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
v2  - https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
v3  - https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
v4  - https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
v5  - https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
v6  - https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
v7  - https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
v8  - https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
v9  - https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/

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


Guillaume Ranquet (15):
  drm/edid: Convert cea_sad helper struct to kernelDoc
  drm/edid: Add cea_sad helpers for freq/length
  drm/mediatek: dpi: move dpi limits to SoC config
  drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
  drm/mediatek: dpi: implement a swap_input toggle in SoC config
  drm/mediatek: dpi: move dimension mask to SoC config
  drm/mediatek: dpi: move hvsize_mask to SoC config
  drm/mediatek: dpi: move swap_shift to SoC config
  drm/mediatek: dpi: move the yuv422_en_bit to SoC config
  drm/mediatek: dpi: move the csc_enable bit to SoC config
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: dpi: Only enable dpi after the bridge is enabled
  drm/meditek: dpi: Add matrix_sel helper
  drm/mediatek: Add mt8195 External DisplayPort support
  drm/mediatek: DP audio support for mt8195

Jitao Shi (1):
  drm/mediatek: add hpd debounce

Markus Schneider-Pargmann (5):
  dt-bindings: mediatek,dpi: Add DPINTF compatible
  dt-bindings: mediatek,dp: Add Display Port binding
  video/hdmi: Add audio_infoframe packing for DP
  phy: phy-mtk-dp: Add driver for DP phy
  drm/mediatek: Add mt8195 Embedded DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml         |   99 +
 .../display/mediatek/mediatek,dpi.yaml        |   13 +-
 MAINTAINERS                                   |    1 +
 drivers/gpu/drm/drm_edid.c                    |   74 +
 drivers/gpu/drm/mediatek/Kconfig              |    8 +
 drivers/gpu/drm/mediatek/Makefile             |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c             | 3419 +++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
 drivers/phy/mediatek/Kconfig                  |    8 +
 drivers/phy/mediatek/Makefile                 |    1 +
 drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
 drivers/video/hdmi.c                          |   82 +-
 include/drm/dp/drm_dp_helper.h                |    2 +
 include/drm/drm_edid.h                        |   26 +-
 include/linux/hdmi.h                          |    7 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
 22 files changed, 4765 insertions(+), 81 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.35.1


^ permalink raw reply	[flat|nested] 450+ messages in thread

* [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-05-23 10:47 ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

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.

This v10 still has some un-answered comments and TODOs for v11.

This has been tested sucessfully on a 5.18-next based "vendor branch".

There's a missing dependency in the mediatek clock framework to allow a
mux clock to change it's parent automatically on rate change.
Without this change, the dpi driver won't properly set the clocks on
mode change and thus nothing will be displayed on screen.

Changes from v9:
- The DP-Phy is back to being a child device of the DP driver (as in v8)
- hot plug detection has been added back to Embedded Display Port... as
  after discussing with mediatek experts, this is needed eventhough the
  Embedded Display port is not un-pluggable
- rebased on linux-next
- simplified/split train_handler function, as suggested by Rex
- added comments on the sleep/delays present in the code
- removed previous patch introducing retries when receiving AUX_DEFER as
  this is already handled in the dp_aux framework
- added max-lane and max-linkrate device tree u8 properties instead of
  hardcoded #defines

Things that are in my todolist for v11:
- retrieve CK/DE support from panel driver instead of hardcoding it into
  the dpi driver
- refcount the dp driver "enabled" status for "future proofing"
- review the drm_dp_helpers for features/functions that have been
  re-implemented in the mediatek dp drivers

Older revisions:
RFC - https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
v1  - https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
v2  - https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
v3  - https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
v4  - https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
v5  - https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
v6  - https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
v7  - https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
v8  - https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
v9  - https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/

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


Guillaume Ranquet (15):
  drm/edid: Convert cea_sad helper struct to kernelDoc
  drm/edid: Add cea_sad helpers for freq/length
  drm/mediatek: dpi: move dpi limits to SoC config
  drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
  drm/mediatek: dpi: implement a swap_input toggle in SoC config
  drm/mediatek: dpi: move dimension mask to SoC config
  drm/mediatek: dpi: move hvsize_mask to SoC config
  drm/mediatek: dpi: move swap_shift to SoC config
  drm/mediatek: dpi: move the yuv422_en_bit to SoC config
  drm/mediatek: dpi: move the csc_enable bit to SoC config
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: dpi: Only enable dpi after the bridge is enabled
  drm/meditek: dpi: Add matrix_sel helper
  drm/mediatek: Add mt8195 External DisplayPort support
  drm/mediatek: DP audio support for mt8195

Jitao Shi (1):
  drm/mediatek: add hpd debounce

Markus Schneider-Pargmann (5):
  dt-bindings: mediatek,dpi: Add DPINTF compatible
  dt-bindings: mediatek,dp: Add Display Port binding
  video/hdmi: Add audio_infoframe packing for DP
  phy: phy-mtk-dp: Add driver for DP phy
  drm/mediatek: Add mt8195 Embedded DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml         |   99 +
 .../display/mediatek/mediatek,dpi.yaml        |   13 +-
 MAINTAINERS                                   |    1 +
 drivers/gpu/drm/drm_edid.c                    |   74 +
 drivers/gpu/drm/mediatek/Kconfig              |    8 +
 drivers/gpu/drm/mediatek/Makefile             |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c             | 3419 +++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
 drivers/phy/mediatek/Kconfig                  |    8 +
 drivers/phy/mediatek/Makefile                 |    1 +
 drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
 drivers/video/hdmi.c                          |   82 +-
 include/drm/dp/drm_dp_helper.h                |    2 +
 include/drm/drm_edid.h                        |   26 +-
 include/linux/hdmi.h                          |    7 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
 22 files changed, 4765 insertions(+), 81 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.35.1


^ permalink raw reply	[flat|nested] 450+ messages in thread

* [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-05-23 10:47 ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

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.

This v10 still has some un-answered comments and TODOs for v11.

This has been tested sucessfully on a 5.18-next based "vendor branch".

There's a missing dependency in the mediatek clock framework to allow a
mux clock to change it's parent automatically on rate change.
Without this change, the dpi driver won't properly set the clocks on
mode change and thus nothing will be displayed on screen.

Changes from v9:
- The DP-Phy is back to being a child device of the DP driver (as in v8)
- hot plug detection has been added back to Embedded Display Port... as
  after discussing with mediatek experts, this is needed eventhough the
  Embedded Display port is not un-pluggable
- rebased on linux-next
- simplified/split train_handler function, as suggested by Rex
- added comments on the sleep/delays present in the code
- removed previous patch introducing retries when receiving AUX_DEFER as
  this is already handled in the dp_aux framework
- added max-lane and max-linkrate device tree u8 properties instead of
  hardcoded #defines

Things that are in my todolist for v11:
- retrieve CK/DE support from panel driver instead of hardcoding it into
  the dpi driver
- refcount the dp driver "enabled" status for "future proofing"
- review the drm_dp_helpers for features/functions that have been
  re-implemented in the mediatek dp drivers

Older revisions:
RFC - https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
v1  - https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
v2  - https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
v3  - https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
v4  - https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
v5  - https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
v6  - https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
v7  - https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
v8  - https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
v9  - https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/

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


Guillaume Ranquet (15):
  drm/edid: Convert cea_sad helper struct to kernelDoc
  drm/edid: Add cea_sad helpers for freq/length
  drm/mediatek: dpi: move dpi limits to SoC config
  drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
  drm/mediatek: dpi: implement a swap_input toggle in SoC config
  drm/mediatek: dpi: move dimension mask to SoC config
  drm/mediatek: dpi: move hvsize_mask to SoC config
  drm/mediatek: dpi: move swap_shift to SoC config
  drm/mediatek: dpi: move the yuv422_en_bit to SoC config
  drm/mediatek: dpi: move the csc_enable bit to SoC config
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: dpi: Only enable dpi after the bridge is enabled
  drm/meditek: dpi: Add matrix_sel helper
  drm/mediatek: Add mt8195 External DisplayPort support
  drm/mediatek: DP audio support for mt8195

Jitao Shi (1):
  drm/mediatek: add hpd debounce

Markus Schneider-Pargmann (5):
  dt-bindings: mediatek,dpi: Add DPINTF compatible
  dt-bindings: mediatek,dp: Add Display Port binding
  video/hdmi: Add audio_infoframe packing for DP
  phy: phy-mtk-dp: Add driver for DP phy
  drm/mediatek: Add mt8195 Embedded DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml         |   99 +
 .../display/mediatek/mediatek,dpi.yaml        |   13 +-
 MAINTAINERS                                   |    1 +
 drivers/gpu/drm/drm_edid.c                    |   74 +
 drivers/gpu/drm/mediatek/Kconfig              |    8 +
 drivers/gpu/drm/mediatek/Makefile             |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c             | 3419 +++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
 drivers/phy/mediatek/Kconfig                  |    8 +
 drivers/phy/mediatek/Makefile                 |    1 +
 drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
 drivers/video/hdmi.c                          |   82 +-
 include/drm/dp/drm_dp_helper.h                |    2 +
 include/drm/drm_edid.h                        |   26 +-
 include/linux/hdmi.h                          |    7 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
 22 files changed, 4765 insertions(+), 81 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.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-05-23 10:47 ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

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.

This v10 still has some un-answered comments and TODOs for v11.

This has been tested sucessfully on a 5.18-next based "vendor branch".

There's a missing dependency in the mediatek clock framework to allow a
mux clock to change it's parent automatically on rate change.
Without this change, the dpi driver won't properly set the clocks on
mode change and thus nothing will be displayed on screen.

Changes from v9:
- The DP-Phy is back to being a child device of the DP driver (as in v8)
- hot plug detection has been added back to Embedded Display Port... as
  after discussing with mediatek experts, this is needed eventhough the
  Embedded Display port is not un-pluggable
- rebased on linux-next
- simplified/split train_handler function, as suggested by Rex
- added comments on the sleep/delays present in the code
- removed previous patch introducing retries when receiving AUX_DEFER as
  this is already handled in the dp_aux framework
- added max-lane and max-linkrate device tree u8 properties instead of
  hardcoded #defines

Things that are in my todolist for v11:
- retrieve CK/DE support from panel driver instead of hardcoding it into
  the dpi driver
- refcount the dp driver "enabled" status for "future proofing"
- review the drm_dp_helpers for features/functions that have been
  re-implemented in the mediatek dp drivers

Older revisions:
RFC - https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
v1  - https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
v2  - https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
v3  - https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
v4  - https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
v5  - https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
v6  - https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
v7  - https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
v8  - https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
v9  - https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/

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


Guillaume Ranquet (15):
  drm/edid: Convert cea_sad helper struct to kernelDoc
  drm/edid: Add cea_sad helpers for freq/length
  drm/mediatek: dpi: move dpi limits to SoC config
  drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
  drm/mediatek: dpi: implement a swap_input toggle in SoC config
  drm/mediatek: dpi: move dimension mask to SoC config
  drm/mediatek: dpi: move hvsize_mask to SoC config
  drm/mediatek: dpi: move swap_shift to SoC config
  drm/mediatek: dpi: move the yuv422_en_bit to SoC config
  drm/mediatek: dpi: move the csc_enable bit to SoC config
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: dpi: Only enable dpi after the bridge is enabled
  drm/meditek: dpi: Add matrix_sel helper
  drm/mediatek: Add mt8195 External DisplayPort support
  drm/mediatek: DP audio support for mt8195

Jitao Shi (1):
  drm/mediatek: add hpd debounce

Markus Schneider-Pargmann (5):
  dt-bindings: mediatek,dpi: Add DPINTF compatible
  dt-bindings: mediatek,dp: Add Display Port binding
  video/hdmi: Add audio_infoframe packing for DP
  phy: phy-mtk-dp: Add driver for DP phy
  drm/mediatek: Add mt8195 Embedded DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml         |   99 +
 .../display/mediatek/mediatek,dpi.yaml        |   13 +-
 MAINTAINERS                                   |    1 +
 drivers/gpu/drm/drm_edid.c                    |   74 +
 drivers/gpu/drm/mediatek/Kconfig              |    8 +
 drivers/gpu/drm/mediatek/Makefile             |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c             | 3419 +++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
 drivers/phy/mediatek/Kconfig                  |    8 +
 drivers/phy/mediatek/Makefile                 |    1 +
 drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
 drivers/video/hdmi.c                          |   82 +-
 include/drm/dp/drm_dp_helper.h                |    2 +
 include/drm/drm_edid.h                        |   26 +-
 include/linux/hdmi.h                          |    7 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
 22 files changed, 4765 insertions(+), 81 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.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-05-23 10:47 ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

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.

This v10 still has some un-answered comments and TODOs for v11.

This has been tested sucessfully on a 5.18-next based "vendor branch".

There's a missing dependency in the mediatek clock framework to allow a
mux clock to change it's parent automatically on rate change.
Without this change, the dpi driver won't properly set the clocks on
mode change and thus nothing will be displayed on screen.

Changes from v9:
- The DP-Phy is back to being a child device of the DP driver (as in v8)
- hot plug detection has been added back to Embedded Display Port... as
  after discussing with mediatek experts, this is needed eventhough the
  Embedded Display port is not un-pluggable
- rebased on linux-next
- simplified/split train_handler function, as suggested by Rex
- added comments on the sleep/delays present in the code
- removed previous patch introducing retries when receiving AUX_DEFER as
  this is already handled in the dp_aux framework
- added max-lane and max-linkrate device tree u8 properties instead of
  hardcoded #defines

Things that are in my todolist for v11:
- retrieve CK/DE support from panel driver instead of hardcoding it into
  the dpi driver
- refcount the dp driver "enabled" status for "future proofing"
- review the drm_dp_helpers for features/functions that have been
  re-implemented in the mediatek dp drivers

Older revisions:
RFC - https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
v1  - https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
v2  - https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
v3  - https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
v4  - https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
v5  - https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
v6  - https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
v7  - https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
v8  - https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
v9  - https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/

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


Guillaume Ranquet (15):
  drm/edid: Convert cea_sad helper struct to kernelDoc
  drm/edid: Add cea_sad helpers for freq/length
  drm/mediatek: dpi: move dpi limits to SoC config
  drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
  drm/mediatek: dpi: implement a swap_input toggle in SoC config
  drm/mediatek: dpi: move dimension mask to SoC config
  drm/mediatek: dpi: move hvsize_mask to SoC config
  drm/mediatek: dpi: move swap_shift to SoC config
  drm/mediatek: dpi: move the yuv422_en_bit to SoC config
  drm/mediatek: dpi: move the csc_enable bit to SoC config
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: dpi: Only enable dpi after the bridge is enabled
  drm/meditek: dpi: Add matrix_sel helper
  drm/mediatek: Add mt8195 External DisplayPort support
  drm/mediatek: DP audio support for mt8195

Jitao Shi (1):
  drm/mediatek: add hpd debounce

Markus Schneider-Pargmann (5):
  dt-bindings: mediatek,dpi: Add DPINTF compatible
  dt-bindings: mediatek,dp: Add Display Port binding
  video/hdmi: Add audio_infoframe packing for DP
  phy: phy-mtk-dp: Add driver for DP phy
  drm/mediatek: Add mt8195 Embedded DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml         |   99 +
 .../display/mediatek/mediatek,dpi.yaml        |   13 +-
 MAINTAINERS                                   |    1 +
 drivers/gpu/drm/drm_edid.c                    |   74 +
 drivers/gpu/drm/mediatek/Kconfig              |    8 +
 drivers/gpu/drm/mediatek/Makefile             |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c             | 3419 +++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
 drivers/phy/mediatek/Kconfig                  |    8 +
 drivers/phy/mediatek/Makefile                 |    1 +
 drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
 drivers/video/hdmi.c                          |   82 +-
 include/drm/dp/drm_dp_helper.h                |    2 +
 include/drm/drm_edid.h                        |   26 +-
 include/linux/hdmi.h                          |    7 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
 22 files changed, 4765 insertions(+), 81 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.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

DPINTF is similar to DPI but does not have the exact same feature set
or register layouts.

DPINTF 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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
 1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
 
 maintainers:
   - CK Hu <ck.hu@mediatek.com>
   - Jitao shi <jitao.shi@mediatek.com>
 
 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 DPINTF 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
@@ -35,12 +36,14 @@ properties:
       - description: Pixel Clock
       - description: Engine Clock
       - description: DPI PLL
+      - description: Optional CK CG Clock
 
   clock-names:
     items:
       - const: pixel
       - const: engine
       - const: pll
+      - const: ck_cg
 
   pinctrl-0: true
   pinctrl-1: true
@@ -54,7 +57,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.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

DPINTF is similar to DPI but does not have the exact same feature set
or register layouts.

DPINTF 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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
 1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
 
 maintainers:
   - CK Hu <ck.hu@mediatek.com>
   - Jitao shi <jitao.shi@mediatek.com>
 
 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 DPINTF 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
@@ -35,12 +36,14 @@ properties:
       - description: Pixel Clock
       - description: Engine Clock
       - description: DPI PLL
+      - description: Optional CK CG Clock
 
   clock-names:
     items:
       - const: pixel
       - const: engine
       - const: pll
+      - const: ck_cg
 
   pinctrl-0: true
   pinctrl-1: true
@@ -54,7 +57,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.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

DPINTF is similar to DPI but does not have the exact same feature set
or register layouts.

DPINTF 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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
 1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
 
 maintainers:
   - CK Hu <ck.hu@mediatek.com>
   - Jitao shi <jitao.shi@mediatek.com>
 
 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 DPINTF 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
@@ -35,12 +36,14 @@ properties:
       - description: Pixel Clock
       - description: Engine Clock
       - description: DPI PLL
+      - description: Optional CK CG Clock
 
   clock-names:
     items:
       - const: pixel
       - const: engine
       - const: pll
+      - const: ck_cg
 
   pinctrl-0: true
   pinctrl-1: true
@@ -54,7 +57,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.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

DPINTF is similar to DPI but does not have the exact same feature set
or register layouts.

DPINTF 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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
 1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
 
 maintainers:
   - CK Hu <ck.hu@mediatek.com>
   - Jitao shi <jitao.shi@mediatek.com>
 
 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 DPINTF 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
@@ -35,12 +36,14 @@ properties:
       - description: Pixel Clock
       - description: Engine Clock
       - description: DPI PLL
+      - description: Optional CK CG Clock
 
   clock-names:
     items:
       - const: pixel
       - const: engine
       - const: pll
+      - const: ck_cg
 
   pinctrl-0: true
   pinctrl-1: true
@@ -54,7 +57,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.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

DPINTF is similar to DPI but does not have the exact same feature set
or register layouts.

DPINTF 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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
 1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
 
 maintainers:
   - CK Hu <ck.hu@mediatek.com>
   - Jitao shi <jitao.shi@mediatek.com>
 
 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 DPINTF 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
@@ -35,12 +36,14 @@ properties:
       - description: Pixel Clock
       - description: Engine Clock
       - description: DPI PLL
+      - description: Optional CK CG Clock
 
   clock-names:
     items:
       - const: pixel
       - const: engine
       - const: pll
+      - const: ck_cg
 
   pinctrl-0: true
   pinctrl-1: true
@@ -54,7 +57,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.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
 1 file changed, 99 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 000000000000..36ae0a6df299
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,99 @@
+# 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 <ck.hu@mediatek.com>
+  - Jitao shi <jitao.shi@mediatek.com>
+
+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
+
+  max-lanes:
+    maxItems: 1
+    description: maximum number of lanes supported by the hardware
+
+  max-linkrate:
+    maxItems: 1
+    description: maximum link rate supported by the hardware
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+  - max-lanes
+  - max-linkrate
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt8195-power.h>
+    edp_tx: edp_tx@1c500000 {
+        compatible = "mediatek,mt8195-dp-tx";
+        reg = <0 0x1c500000 0 0x8000>;
+        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&edp_pin>;
+        max-lanes = /bits/ 8 <4>;
+        max-linkrate = /bits/ 8 <0x1e>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                edp_in: endpoint {
+                    remote-endpoint = <&dp_intf0_out>;
+                };
+            };
+            port@1 {
+                reg = <1>;
+                edp_out: endpoint {
+                	remote-endpoint = <&panel_in>;
+                };
+            };
+        };
+    };
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
 1 file changed, 99 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 000000000000..36ae0a6df299
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,99 @@
+# 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 <ck.hu@mediatek.com>
+  - Jitao shi <jitao.shi@mediatek.com>
+
+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
+
+  max-lanes:
+    maxItems: 1
+    description: maximum number of lanes supported by the hardware
+
+  max-linkrate:
+    maxItems: 1
+    description: maximum link rate supported by the hardware
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+  - max-lanes
+  - max-linkrate
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt8195-power.h>
+    edp_tx: edp_tx@1c500000 {
+        compatible = "mediatek,mt8195-dp-tx";
+        reg = <0 0x1c500000 0 0x8000>;
+        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&edp_pin>;
+        max-lanes = /bits/ 8 <4>;
+        max-linkrate = /bits/ 8 <0x1e>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                edp_in: endpoint {
+                    remote-endpoint = <&dp_intf0_out>;
+                };
+            };
+            port@1 {
+                reg = <1>;
+                edp_out: endpoint {
+                	remote-endpoint = <&panel_in>;
+                };
+            };
+        };
+    };
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
 1 file changed, 99 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 000000000000..36ae0a6df299
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,99 @@
+# 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 <ck.hu@mediatek.com>
+  - Jitao shi <jitao.shi@mediatek.com>
+
+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
+
+  max-lanes:
+    maxItems: 1
+    description: maximum number of lanes supported by the hardware
+
+  max-linkrate:
+    maxItems: 1
+    description: maximum link rate supported by the hardware
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+  - max-lanes
+  - max-linkrate
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt8195-power.h>
+    edp_tx: edp_tx@1c500000 {
+        compatible = "mediatek,mt8195-dp-tx";
+        reg = <0 0x1c500000 0 0x8000>;
+        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&edp_pin>;
+        max-lanes = /bits/ 8 <4>;
+        max-linkrate = /bits/ 8 <0x1e>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                edp_in: endpoint {
+                    remote-endpoint = <&dp_intf0_out>;
+                };
+            };
+            port@1 {
+                reg = <1>;
+                edp_out: endpoint {
+                	remote-endpoint = <&panel_in>;
+                };
+            };
+        };
+    };
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
 1 file changed, 99 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 000000000000..36ae0a6df299
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,99 @@
+# 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 <ck.hu@mediatek.com>
+  - Jitao shi <jitao.shi@mediatek.com>
+
+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
+
+  max-lanes:
+    maxItems: 1
+    description: maximum number of lanes supported by the hardware
+
+  max-linkrate:
+    maxItems: 1
+    description: maximum link rate supported by the hardware
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+  - max-lanes
+  - max-linkrate
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt8195-power.h>
+    edp_tx: edp_tx@1c500000 {
+        compatible = "mediatek,mt8195-dp-tx";
+        reg = <0 0x1c500000 0 0x8000>;
+        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&edp_pin>;
+        max-lanes = /bits/ 8 <4>;
+        max-linkrate = /bits/ 8 <0x1e>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                edp_in: endpoint {
+                    remote-endpoint = <&dp_intf0_out>;
+                };
+            };
+            port@1 {
+                reg = <1>;
+                edp_out: endpoint {
+                	remote-endpoint = <&panel_in>;
+                };
+            };
+        };
+    };
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
 1 file changed, 99 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 000000000000..36ae0a6df299
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,99 @@
+# 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 <ck.hu@mediatek.com>
+  - Jitao shi <jitao.shi@mediatek.com>
+
+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
+
+  max-lanes:
+    maxItems: 1
+    description: maximum number of lanes supported by the hardware
+
+  max-linkrate:
+    maxItems: 1
+    description: maximum link rate supported by the hardware
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+  - max-lanes
+  - max-linkrate
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt8195-power.h>
+    edp_tx: edp_tx@1c500000 {
+        compatible = "mediatek,mt8195-dp-tx";
+        reg = <0 0x1c500000 0 0x8000>;
+        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&edp_pin>;
+        max-lanes = /bits/ 8 <4>;
+        max-linkrate = /bits/ 8 <0x1e>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                edp_in: endpoint {
+                    remote-endpoint = <&dp_intf0_out>;
+                };
+            };
+            port@1 {
+                reg = <1>;
+                edp_out: endpoint {
+                	remote-endpoint = <&panel_in>;
+                };
+            };
+        };
+    };
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 include/drm/drm_edid.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 144c495b99c4..37c420423625 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -359,12 +359,18 @@ struct edid {
 
 #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
 
-/* Short Audio Descriptor */
+/**
+ * struct cea_sad - Short Audio Descriptor.
+ * @format: See HDMI_AUDIO_CODING_TYPE_*.
+ * @channels: max number of channels - 1.
+ * @freq: See CEA_SAD_FREQ_*.
+ * @byte2: meaning depends on format.
+ */
 struct cea_sad {
 	u8 format;
-	u8 channels; /* max number of channels - 1 */
+	u8 channels;
 	u8 freq;
-	u8 byte2; /* meaning depends on format */
+	u8 byte2;
 };
 
 struct drm_encoder;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 include/drm/drm_edid.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 144c495b99c4..37c420423625 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -359,12 +359,18 @@ struct edid {
 
 #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
 
-/* Short Audio Descriptor */
+/**
+ * struct cea_sad - Short Audio Descriptor.
+ * @format: See HDMI_AUDIO_CODING_TYPE_*.
+ * @channels: max number of channels - 1.
+ * @freq: See CEA_SAD_FREQ_*.
+ * @byte2: meaning depends on format.
+ */
 struct cea_sad {
 	u8 format;
-	u8 channels; /* max number of channels - 1 */
+	u8 channels;
 	u8 freq;
-	u8 byte2; /* meaning depends on format */
+	u8 byte2;
 };
 
 struct drm_encoder;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 include/drm/drm_edid.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 144c495b99c4..37c420423625 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -359,12 +359,18 @@ struct edid {
 
 #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
 
-/* Short Audio Descriptor */
+/**
+ * struct cea_sad - Short Audio Descriptor.
+ * @format: See HDMI_AUDIO_CODING_TYPE_*.
+ * @channels: max number of channels - 1.
+ * @freq: See CEA_SAD_FREQ_*.
+ * @byte2: meaning depends on format.
+ */
 struct cea_sad {
 	u8 format;
-	u8 channels; /* max number of channels - 1 */
+	u8 channels;
 	u8 freq;
-	u8 byte2; /* meaning depends on format */
+	u8 byte2;
 };
 
 struct drm_encoder;
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 include/drm/drm_edid.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 144c495b99c4..37c420423625 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -359,12 +359,18 @@ struct edid {
 
 #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
 
-/* Short Audio Descriptor */
+/**
+ * struct cea_sad - Short Audio Descriptor.
+ * @format: See HDMI_AUDIO_CODING_TYPE_*.
+ * @channels: max number of channels - 1.
+ * @freq: See CEA_SAD_FREQ_*.
+ * @byte2: meaning depends on format.
+ */
 struct cea_sad {
 	u8 format;
-	u8 channels; /* max number of channels - 1 */
+	u8 channels;
 	u8 freq;
-	u8 byte2; /* meaning depends on format */
+	u8 byte2;
 };
 
 struct drm_encoder;
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 include/drm/drm_edid.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 144c495b99c4..37c420423625 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -359,12 +359,18 @@ struct edid {
 
 #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
 
-/* Short Audio Descriptor */
+/**
+ * struct cea_sad - Short Audio Descriptor.
+ * @format: See HDMI_AUDIO_CODING_TYPE_*.
+ * @channels: max number of channels - 1.
+ * @freq: See CEA_SAD_FREQ_*.
+ * @byte2: meaning depends on format.
+ */
 struct cea_sad {
 	u8 format;
-	u8 channels; /* max number of channels - 1 */
+	u8 channels;
 	u8 freq;
-	u8 byte2; /* meaning depends on format */
+	u8 byte2;
 };
 
 struct drm_encoder;
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_edid.h     | 14 ++++++++
 2 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..61ef1b1c972c 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4758,6 +4758,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 37c420423625..7a939cb95b38 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -373,6 +373,18 @@ struct cea_sad {
 	u8 byte2;
 };
 
+#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;
@@ -380,6 +392,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.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_edid.h     | 14 ++++++++
 2 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..61ef1b1c972c 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4758,6 +4758,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 37c420423625..7a939cb95b38 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -373,6 +373,18 @@ struct cea_sad {
 	u8 byte2;
 };
 
+#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;
@@ -380,6 +392,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.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_edid.h     | 14 ++++++++
 2 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..61ef1b1c972c 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4758,6 +4758,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 37c420423625..7a939cb95b38 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -373,6 +373,18 @@ struct cea_sad {
 	u8 byte2;
 };
 
+#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;
@@ -380,6 +392,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.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_edid.h     | 14 ++++++++
 2 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..61ef1b1c972c 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4758,6 +4758,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 37c420423625..7a939cb95b38 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -373,6 +373,18 @@ struct cea_sad {
 	u8 byte2;
 };
 
+#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;
@@ -380,6 +392,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.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_edid.h     | 14 ++++++++
 2 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..61ef1b1c972c 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4758,6 +4758,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 37c420423625..7a939cb95b38 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -373,6 +373,18 @@ struct cea_sad {
 	u8 byte2;
 };
 
+#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;
@@ -380,6 +392,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.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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.

Also constify the frame parameter in hdmi_audio_infoframe_check() as
it is passed to hdmi_audio_infoframe_check_only() which expects a const.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
 include/drm/dp/drm_dp_helper.h |  2 +
 include/linux/hdmi.h           |  7 ++-
 3 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..5f50237554ed 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <drm/dp/drm_dp_helper.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/errno.h>
@@ -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,43 @@ 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.HB3 = (dp_version & 0x3f) << 2;
+
+	hdmi_audio_infoframe_pack_payload(frame, sdp->db);
+
+	return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @frame: HDMI vendor infoframe
diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 51e02cf75277..d4adb479263e 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -1576,6 +1576,8 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw);
 #define DP_SDP_VSC_EXT_CEA		0x21 /* DP 1.4 */
 /* 0x80+ CEA-861 infoframe types */
 
+#define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b
+
 /**
  * struct dp_sdp_header - DP secondary data packet header
  * @HB0: Secondary Data Packet ID
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index c8ec982ff498..2f4dcc8d060e 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -336,7 +336,12 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 				  void *buffer, size_t size);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size);
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame);
+
+struct dp_sdp;
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+				 struct dp_sdp *sdp, u8 dp_version);
 
 enum hdmi_3d_structure {
 	HDMI_3D_STRUCTURE_INVALID = -1,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

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.

Also constify the frame parameter in hdmi_audio_infoframe_check() as
it is passed to hdmi_audio_infoframe_check_only() which expects a const.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
 include/drm/dp/drm_dp_helper.h |  2 +
 include/linux/hdmi.h           |  7 ++-
 3 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..5f50237554ed 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <drm/dp/drm_dp_helper.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/errno.h>
@@ -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,43 @@ 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.HB3 = (dp_version & 0x3f) << 2;
+
+	hdmi_audio_infoframe_pack_payload(frame, sdp->db);
+
+	return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @frame: HDMI vendor infoframe
diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 51e02cf75277..d4adb479263e 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -1576,6 +1576,8 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw);
 #define DP_SDP_VSC_EXT_CEA		0x21 /* DP 1.4 */
 /* 0x80+ CEA-861 infoframe types */
 
+#define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b
+
 /**
  * struct dp_sdp_header - DP secondary data packet header
  * @HB0: Secondary Data Packet ID
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index c8ec982ff498..2f4dcc8d060e 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -336,7 +336,12 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 				  void *buffer, size_t size);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size);
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame);
+
+struct dp_sdp;
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+				 struct dp_sdp *sdp, u8 dp_version);
 
 enum hdmi_3d_structure {
 	HDMI_3D_STRUCTURE_INVALID = -1,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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.

Also constify the frame parameter in hdmi_audio_infoframe_check() as
it is passed to hdmi_audio_infoframe_check_only() which expects a const.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
 include/drm/dp/drm_dp_helper.h |  2 +
 include/linux/hdmi.h           |  7 ++-
 3 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..5f50237554ed 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <drm/dp/drm_dp_helper.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/errno.h>
@@ -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,43 @@ 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.HB3 = (dp_version & 0x3f) << 2;
+
+	hdmi_audio_infoframe_pack_payload(frame, sdp->db);
+
+	return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @frame: HDMI vendor infoframe
diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 51e02cf75277..d4adb479263e 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -1576,6 +1576,8 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw);
 #define DP_SDP_VSC_EXT_CEA		0x21 /* DP 1.4 */
 /* 0x80+ CEA-861 infoframe types */
 
+#define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b
+
 /**
  * struct dp_sdp_header - DP secondary data packet header
  * @HB0: Secondary Data Packet ID
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index c8ec982ff498..2f4dcc8d060e 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -336,7 +336,12 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 				  void *buffer, size_t size);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size);
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame);
+
+struct dp_sdp;
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+				 struct dp_sdp *sdp, u8 dp_version);
 
 enum hdmi_3d_structure {
 	HDMI_3D_STRUCTURE_INVALID = -1,
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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.

Also constify the frame parameter in hdmi_audio_infoframe_check() as
it is passed to hdmi_audio_infoframe_check_only() which expects a const.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
 include/drm/dp/drm_dp_helper.h |  2 +
 include/linux/hdmi.h           |  7 ++-
 3 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..5f50237554ed 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <drm/dp/drm_dp_helper.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/errno.h>
@@ -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,43 @@ 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.HB3 = (dp_version & 0x3f) << 2;
+
+	hdmi_audio_infoframe_pack_payload(frame, sdp->db);
+
+	return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @frame: HDMI vendor infoframe
diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 51e02cf75277..d4adb479263e 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -1576,6 +1576,8 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw);
 #define DP_SDP_VSC_EXT_CEA		0x21 /* DP 1.4 */
 /* 0x80+ CEA-861 infoframe types */
 
+#define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b
+
 /**
  * struct dp_sdp_header - DP secondary data packet header
  * @HB0: Secondary Data Packet ID
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index c8ec982ff498..2f4dcc8d060e 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -336,7 +336,12 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 				  void *buffer, size_t size);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size);
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame);
+
+struct dp_sdp;
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+				 struct dp_sdp *sdp, u8 dp_version);
 
 enum hdmi_3d_structure {
 	HDMI_3D_STRUCTURE_INVALID = -1,
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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.

Also constify the frame parameter in hdmi_audio_infoframe_check() as
it is passed to hdmi_audio_infoframe_check_only() which expects a const.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
 include/drm/dp/drm_dp_helper.h |  2 +
 include/linux/hdmi.h           |  7 ++-
 3 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..5f50237554ed 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <drm/dp/drm_dp_helper.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/errno.h>
@@ -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,43 @@ 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.HB3 = (dp_version & 0x3f) << 2;
+
+	hdmi_audio_infoframe_pack_payload(frame, sdp->db);
+
+	return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @frame: HDMI vendor infoframe
diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 51e02cf75277..d4adb479263e 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -1576,6 +1576,8 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw);
 #define DP_SDP_VSC_EXT_CEA		0x21 /* DP 1.4 */
 /* 0x80+ CEA-861 infoframe types */
 
+#define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b
+
 /**
  * struct dp_sdp_header - DP secondary data packet header
  * @HB0: Secondary Data Packet ID
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index c8ec982ff498..2f4dcc8d060e 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -336,7 +336,12 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 				  void *buffer, size_t size);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size);
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame);
+
+struct dp_sdp;
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+				 struct dp_sdp *sdp, u8 dp_version);
 
 enum hdmi_3d_structure {
 	HDMI_3D_STRUCTURE_INVALID = -1,
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 06/21] drm/mediatek: dpi: move dpi limits to SoC config
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the dpi limits to the SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..4746eb342567 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	const struct mtk_dpi_yc_limit *limit;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -235,9 +236,10 @@ static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
 }
 
-static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
-					 struct mtk_dpi_yc_limit *limit)
+static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
 {
+	const struct mtk_dpi_yc_limit *limit = dpi->conf->limit;
+
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT,
 		     Y_LIMINT_BOT_MASK);
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP,
@@ -449,7 +451,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 				    struct drm_display_mode *mode)
 {
-	struct mtk_dpi_yc_limit limit;
 	struct mtk_dpi_polarities dpi_pol;
 	struct mtk_dpi_sync_param hsync;
 	struct mtk_dpi_sync_param vsync_lodd = { 0 };
@@ -484,11 +485,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
 		pll_rate, vm.pixelclock);
 
-	limit.c_bottom = 0x0010;
-	limit.c_top = 0x0FE0;
-	limit.y_bottom = 0x0010;
-	limit.y_top = 0x0FE0;
-
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
 	dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
@@ -536,7 +532,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	else
 		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
 
-	mtk_dpi_config_channel_limit(dpi, &limit);
+	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
 	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
@@ -790,12 +786,20 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
+	.c_bottom = 0x0010,
+	.c_top = 0x0FE0,
+	.y_bottom = 0x0010,
+	.y_top = 0x0FE0,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
@@ -805,6 +809,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
@@ -813,6 +818,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
@@ -821,6 +827,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static int mtk_dpi_probe(struct platform_device *pdev)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 06/21] drm/mediatek: dpi: move dpi limits to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Add flexibility by moving the dpi limits to the SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..4746eb342567 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	const struct mtk_dpi_yc_limit *limit;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -235,9 +236,10 @@ static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
 }
 
-static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
-					 struct mtk_dpi_yc_limit *limit)
+static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
 {
+	const struct mtk_dpi_yc_limit *limit = dpi->conf->limit;
+
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT,
 		     Y_LIMINT_BOT_MASK);
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP,
@@ -449,7 +451,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 				    struct drm_display_mode *mode)
 {
-	struct mtk_dpi_yc_limit limit;
 	struct mtk_dpi_polarities dpi_pol;
 	struct mtk_dpi_sync_param hsync;
 	struct mtk_dpi_sync_param vsync_lodd = { 0 };
@@ -484,11 +485,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
 		pll_rate, vm.pixelclock);
 
-	limit.c_bottom = 0x0010;
-	limit.c_top = 0x0FE0;
-	limit.y_bottom = 0x0010;
-	limit.y_top = 0x0FE0;
-
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
 	dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
@@ -536,7 +532,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	else
 		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
 
-	mtk_dpi_config_channel_limit(dpi, &limit);
+	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
 	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
@@ -790,12 +786,20 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
+	.c_bottom = 0x0010,
+	.c_top = 0x0FE0,
+	.y_bottom = 0x0010,
+	.y_top = 0x0FE0,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
@@ -805,6 +809,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
@@ -813,6 +818,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
@@ -821,6 +827,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static int mtk_dpi_probe(struct platform_device *pdev)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 06/21] drm/mediatek: dpi: move dpi limits to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the dpi limits to the SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..4746eb342567 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	const struct mtk_dpi_yc_limit *limit;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -235,9 +236,10 @@ static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
 }
 
-static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
-					 struct mtk_dpi_yc_limit *limit)
+static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
 {
+	const struct mtk_dpi_yc_limit *limit = dpi->conf->limit;
+
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT,
 		     Y_LIMINT_BOT_MASK);
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP,
@@ -449,7 +451,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 				    struct drm_display_mode *mode)
 {
-	struct mtk_dpi_yc_limit limit;
 	struct mtk_dpi_polarities dpi_pol;
 	struct mtk_dpi_sync_param hsync;
 	struct mtk_dpi_sync_param vsync_lodd = { 0 };
@@ -484,11 +485,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
 		pll_rate, vm.pixelclock);
 
-	limit.c_bottom = 0x0010;
-	limit.c_top = 0x0FE0;
-	limit.y_bottom = 0x0010;
-	limit.y_top = 0x0FE0;
-
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
 	dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
@@ -536,7 +532,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	else
 		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
 
-	mtk_dpi_config_channel_limit(dpi, &limit);
+	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
 	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
@@ -790,12 +786,20 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
+	.c_bottom = 0x0010,
+	.c_top = 0x0FE0,
+	.y_bottom = 0x0010,
+	.y_top = 0x0FE0,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
@@ -805,6 +809,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
@@ -813,6 +818,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
@@ -821,6 +827,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static int mtk_dpi_probe(struct platform_device *pdev)
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 06/21] drm/mediatek: dpi: move dpi limits to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the dpi limits to the SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..4746eb342567 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	const struct mtk_dpi_yc_limit *limit;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -235,9 +236,10 @@ static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
 }
 
-static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
-					 struct mtk_dpi_yc_limit *limit)
+static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
 {
+	const struct mtk_dpi_yc_limit *limit = dpi->conf->limit;
+
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT,
 		     Y_LIMINT_BOT_MASK);
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP,
@@ -449,7 +451,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 				    struct drm_display_mode *mode)
 {
-	struct mtk_dpi_yc_limit limit;
 	struct mtk_dpi_polarities dpi_pol;
 	struct mtk_dpi_sync_param hsync;
 	struct mtk_dpi_sync_param vsync_lodd = { 0 };
@@ -484,11 +485,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
 		pll_rate, vm.pixelclock);
 
-	limit.c_bottom = 0x0010;
-	limit.c_top = 0x0FE0;
-	limit.y_bottom = 0x0010;
-	limit.y_top = 0x0FE0;
-
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
 	dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
@@ -536,7 +532,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	else
 		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
 
-	mtk_dpi_config_channel_limit(dpi, &limit);
+	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
 	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
@@ -790,12 +786,20 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
+	.c_bottom = 0x0010,
+	.c_top = 0x0FE0,
+	.y_bottom = 0x0010,
+	.y_top = 0x0FE0,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
@@ -805,6 +809,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
@@ -813,6 +818,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
@@ -821,6 +827,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static int mtk_dpi_probe(struct platform_device *pdev)
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 06/21] drm/mediatek: dpi: move dpi limits to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the dpi limits to the SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..4746eb342567 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	const struct mtk_dpi_yc_limit *limit;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -235,9 +236,10 @@ static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
 }
 
-static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
-					 struct mtk_dpi_yc_limit *limit)
+static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
 {
+	const struct mtk_dpi_yc_limit *limit = dpi->conf->limit;
+
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT,
 		     Y_LIMINT_BOT_MASK);
 	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP,
@@ -449,7 +451,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 				    struct drm_display_mode *mode)
 {
-	struct mtk_dpi_yc_limit limit;
 	struct mtk_dpi_polarities dpi_pol;
 	struct mtk_dpi_sync_param hsync;
 	struct mtk_dpi_sync_param vsync_lodd = { 0 };
@@ -484,11 +485,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
 		pll_rate, vm.pixelclock);
 
-	limit.c_bottom = 0x0010;
-	limit.c_top = 0x0FE0;
-	limit.y_bottom = 0x0010;
-	limit.y_top = 0x0FE0;
-
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
 	dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
@@ -536,7 +532,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	else
 		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
 
-	mtk_dpi_config_channel_limit(dpi, &limit);
+	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
 	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
@@ -790,12 +786,20 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
+	.c_bottom = 0x0010,
+	.c_top = 0x0FE0,
+	.y_bottom = 0x0010,
+	.y_top = 0x0FE0,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
@@ -805,6 +809,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
@@ -813,6 +818,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
@@ -821,6 +827,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.limit = &mtk_dpi_limit,
 };
 
 static int mtk_dpi_probe(struct platform_device *pdev)
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Adds a bit of flexibility to support SoCs without CK/DE pol support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4746eb342567..545a1337cc89 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	bool is_ck_de_pol;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
 			       struct mtk_dpi_polarities *dpi_pol)
 {
 	unsigned int pol;
+	unsigned int mask;
 
-	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
-	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
-	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
+	mask = HSYNC_POL | VSYNC_POL;
+	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
 	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
-		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
+	if (dpi->conf->is_ck_de_pol) {
+		mask |= CK_POL | DE_POL;
+		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
+			0 : CK_POL) |
+		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
+			0 : DE_POL);
+	}
+
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
 }
 
 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
@@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Adds a bit of flexibility to support SoCs without CK/DE pol support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4746eb342567..545a1337cc89 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	bool is_ck_de_pol;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
 			       struct mtk_dpi_polarities *dpi_pol)
 {
 	unsigned int pol;
+	unsigned int mask;
 
-	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
-	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
-	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
+	mask = HSYNC_POL | VSYNC_POL;
+	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
 	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
-		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
+	if (dpi->conf->is_ck_de_pol) {
+		mask |= CK_POL | DE_POL;
+		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
+			0 : CK_POL) |
+		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
+			0 : DE_POL);
+	}
+
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
 }
 
 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
@@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Adds a bit of flexibility to support SoCs without CK/DE pol support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4746eb342567..545a1337cc89 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	bool is_ck_de_pol;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
 			       struct mtk_dpi_polarities *dpi_pol)
 {
 	unsigned int pol;
+	unsigned int mask;
 
-	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
-	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
-	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
+	mask = HSYNC_POL | VSYNC_POL;
+	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
 	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
-		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
+	if (dpi->conf->is_ck_de_pol) {
+		mask |= CK_POL | DE_POL;
+		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
+			0 : CK_POL) |
+		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
+			0 : DE_POL);
+	}
+
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
 }
 
 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
@@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Adds a bit of flexibility to support SoCs without CK/DE pol support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4746eb342567..545a1337cc89 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	bool is_ck_de_pol;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
 			       struct mtk_dpi_polarities *dpi_pol)
 {
 	unsigned int pol;
+	unsigned int mask;
 
-	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
-	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
-	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
+	mask = HSYNC_POL | VSYNC_POL;
+	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
 	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
-		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
+	if (dpi->conf->is_ck_de_pol) {
+		mask |= CK_POL | DE_POL;
+		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
+			0 : CK_POL) |
+		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
+			0 : DE_POL);
+	}
+
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
 }
 
 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
@@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Adds a bit of flexibility to support SoCs without CK/DE pol support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4746eb342567..545a1337cc89 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	bool is_ck_de_pol;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
 			       struct mtk_dpi_polarities *dpi_pol)
 {
 	unsigned int pol;
+	unsigned int mask;
 
-	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
-	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
-	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
+	mask = HSYNC_POL | VSYNC_POL;
+	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
 	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
-		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
+	if (dpi->conf->is_ck_de_pol) {
+		mask |= CK_POL | DE_POL;
+		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
+			0 : CK_POL) |
+		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
+			0 : DE_POL);
+	}
+
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
 }
 
 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
@@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_ck_de_pol = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Adds a bit of flexibility to support SoCs without swap_input support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 545a1337cc89..454f8563efae 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -126,6 +126,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool swap_input_support;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
 	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, true);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	} else {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, false);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	}
 }
@@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Adds a bit of flexibility to support SoCs without swap_input support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 545a1337cc89..454f8563efae 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -126,6 +126,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool swap_input_support;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
 	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, true);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	} else {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, false);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	}
 }
@@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Adds a bit of flexibility to support SoCs without swap_input support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 545a1337cc89..454f8563efae 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -126,6 +126,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool swap_input_support;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
 	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, true);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	} else {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, false);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	}
 }
@@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Adds a bit of flexibility to support SoCs without swap_input support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 545a1337cc89..454f8563efae 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -126,6 +126,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool swap_input_support;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
 	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, true);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	} else {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, false);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	}
 }
@@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Adds a bit of flexibility to support SoCs without swap_input support

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 545a1337cc89..454f8563efae 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -126,6 +126,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool swap_input_support;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
 	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, true);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	} else {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, false);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (dpi->conf->swap_input_support)
+			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	}
 }
@@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
+	.swap_input_support = true,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Add flexibility by moving the dimension mask to the SoC config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 454f8563efae..bf098f36a466 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -127,6 +127,8 @@ struct mtk_dpi_conf {
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
 	bool swap_input_support;
+	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
+	u32 dimension_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
@@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the dimension mask to the SoC config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 454f8563efae..bf098f36a466 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -127,6 +127,8 @@ struct mtk_dpi_conf {
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
 	bool swap_input_support;
+	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
+	u32 dimension_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
@@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the dimension mask to the SoC config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 454f8563efae..bf098f36a466 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -127,6 +127,8 @@ struct mtk_dpi_conf {
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
 	bool swap_input_support;
+	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
+	u32 dimension_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
@@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the dimension mask to the SoC config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 454f8563efae..bf098f36a466 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -127,6 +127,8 @@ struct mtk_dpi_conf {
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
 	bool swap_input_support;
+	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
+	u32 dimension_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
@@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the dimension mask to the SoC config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 454f8563efae..bf098f36a466 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -127,6 +127,8 @@ struct mtk_dpi_conf {
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
 	bool swap_input_support;
+	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
+	u32 dimension_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
@@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Add flexibility by moving the hvsize mask to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index bf098f36a466..6eeda222a973 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -129,6 +129,8 @@ struct mtk_dpi_conf {
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
+	/* HSIZE and VSIZE mask (no shift) */
+	u32 hvsize_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
 
 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 {
-	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
-	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
+	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
+		     dpi->conf->hvsize_mask << HSIZE);
+	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
+		     dpi->conf->hvsize_mask << VSIZE);
 }
 
 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
@@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the hvsize mask to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index bf098f36a466..6eeda222a973 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -129,6 +129,8 @@ struct mtk_dpi_conf {
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
+	/* HSIZE and VSIZE mask (no shift) */
+	u32 hvsize_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
 
 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 {
-	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
-	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
+	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
+		     dpi->conf->hvsize_mask << HSIZE);
+	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
+		     dpi->conf->hvsize_mask << VSIZE);
 }
 
 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
@@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the hvsize mask to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index bf098f36a466..6eeda222a973 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -129,6 +129,8 @@ struct mtk_dpi_conf {
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
+	/* HSIZE and VSIZE mask (no shift) */
+	u32 hvsize_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
 
 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 {
-	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
-	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
+	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
+		     dpi->conf->hvsize_mask << HSIZE);
+	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
+		     dpi->conf->hvsize_mask << VSIZE);
 }
 
 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
@@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the hvsize mask to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index bf098f36a466..6eeda222a973 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -129,6 +129,8 @@ struct mtk_dpi_conf {
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
+	/* HSIZE and VSIZE mask (no shift) */
+	u32 hvsize_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
 
 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 {
-	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
-	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
+	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
+		     dpi->conf->hvsize_mask << HSIZE);
+	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
+		     dpi->conf->hvsize_mask << VSIZE);
 }
 
 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
@@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the hvsize mask to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index bf098f36a466..6eeda222a973 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -129,6 +129,8 @@ struct mtk_dpi_conf {
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
+	/* HSIZE and VSIZE mask (no shift) */
+	u32 hvsize_mask;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
 
 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 {
-	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
-	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
+	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
+		     dpi->conf->hvsize_mask << HSIZE);
+	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
+		     dpi->conf->hvsize_mask << VSIZE);
 }
 
 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
@@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.is_ck_de_pol = true,
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Add flexibility by moving the swap shift value to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6eeda222a973..6d4d8c6ec47d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -131,6 +131,7 @@ struct mtk_dpi_conf {
 	u32 dimension_mask;
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
+	u32 channel_swap_shift;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 		break;
 	}
 
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf->channel_swap_shift,
+		     CH_SWAP_MASK);
 }
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
@@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Rex-BC Chen, AngeloGioacchino Del Regno, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the swap shift value to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6eeda222a973..6d4d8c6ec47d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -131,6 +131,7 @@ struct mtk_dpi_conf {
 	u32 dimension_mask;
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
+	u32 channel_swap_shift;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 		break;
 	}
 
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf->channel_swap_shift,
+		     CH_SWAP_MASK);
 }
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
@@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Rex-BC Chen, AngeloGioacchino Del Regno, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the swap shift value to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6eeda222a973..6d4d8c6ec47d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -131,6 +131,7 @@ struct mtk_dpi_conf {
 	u32 dimension_mask;
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
+	u32 channel_swap_shift;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 		break;
 	}
 
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf->channel_swap_shift,
+		     CH_SWAP_MASK);
 }
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
@@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Rex-BC Chen, AngeloGioacchino Del Regno, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the swap shift value to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6eeda222a973..6d4d8c6ec47d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -131,6 +131,7 @@ struct mtk_dpi_conf {
 	u32 dimension_mask;
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
+	u32 channel_swap_shift;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 		break;
 	}
 
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf->channel_swap_shift,
+		     CH_SWAP_MASK);
 }
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
@@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Rex-BC Chen, AngeloGioacchino Del Regno, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the swap shift value to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6eeda222a973..6d4d8c6ec47d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -131,6 +131,7 @@ struct mtk_dpi_conf {
 	u32 dimension_mask;
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
+	u32 channel_swap_shift;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 		break;
 	}
 
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf->channel_swap_shift,
+		     CH_SWAP_MASK);
 }
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
@@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.swap_input_support = true,
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Add flexibility by moving the yuv422 en bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6d4d8c6ec47d..40254cd9d168 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -132,6 +132,7 @@ struct mtk_dpi_conf {
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
+	u32 yuv422_en_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0,
+		     dpi->conf->yuv422_en_bit);
 }
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
@@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the yuv422 en bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6d4d8c6ec47d..40254cd9d168 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -132,6 +132,7 @@ struct mtk_dpi_conf {
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
+	u32 yuv422_en_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0,
+		     dpi->conf->yuv422_en_bit);
 }
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
@@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the yuv422 en bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6d4d8c6ec47d..40254cd9d168 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -132,6 +132,7 @@ struct mtk_dpi_conf {
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
+	u32 yuv422_en_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0,
+		     dpi->conf->yuv422_en_bit);
 }
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
@@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the yuv422 en bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6d4d8c6ec47d..40254cd9d168 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -132,6 +132,7 @@ struct mtk_dpi_conf {
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
+	u32 yuv422_en_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0,
+		     dpi->conf->yuv422_en_bit);
 }
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
@@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the yuv422 en bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 6d4d8c6ec47d..40254cd9d168 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -132,6 +132,7 @@ struct mtk_dpi_conf {
 	/* HSIZE and VSIZE mask (no shift) */
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
+	u32 yuv422_en_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0,
+		     dpi->conf->yuv422_en_bit);
 }
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
@@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.dimension_mask = HPW_MASK,
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 13/21] drm/mediatek: dpi: move the csc_enable bit to SoC config
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Add flexibility by moving the csc_enable bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 40254cd9d168..eb969c5c5c2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -133,6 +133,7 @@ struct mtk_dpi_conf {
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
 	u32 yuv422_en_bit;
+	u32 csc_enable_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -363,7 +364,8 @@ static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0,
+		     dpi->conf->csc_enable_bit);
 }
 
 static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
@@ -827,6 +829,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -843,6 +846,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -858,6 +862,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -873,6 +878,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 13/21] drm/mediatek: dpi: move the csc_enable bit to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the csc_enable bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 40254cd9d168..eb969c5c5c2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -133,6 +133,7 @@ struct mtk_dpi_conf {
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
 	u32 yuv422_en_bit;
+	u32 csc_enable_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -363,7 +364,8 @@ static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0,
+		     dpi->conf->csc_enable_bit);
 }
 
 static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
@@ -827,6 +829,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -843,6 +846,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -858,6 +862,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -873,6 +878,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 13/21] drm/mediatek: dpi: move the csc_enable bit to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the csc_enable bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 40254cd9d168..eb969c5c5c2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -133,6 +133,7 @@ struct mtk_dpi_conf {
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
 	u32 yuv422_en_bit;
+	u32 csc_enable_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -363,7 +364,8 @@ static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0,
+		     dpi->conf->csc_enable_bit);
 }
 
 static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
@@ -827,6 +829,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -843,6 +846,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -858,6 +862,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -873,6 +878,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 13/21] drm/mediatek: dpi: move the csc_enable bit to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the csc_enable bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 40254cd9d168..eb969c5c5c2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -133,6 +133,7 @@ struct mtk_dpi_conf {
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
 	u32 yuv422_en_bit;
+	u32 csc_enable_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -363,7 +364,8 @@ static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0,
+		     dpi->conf->csc_enable_bit);
 }
 
 static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
@@ -827,6 +829,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -843,6 +846,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -858,6 +862,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -873,6 +878,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 13/21] drm/mediatek: dpi: move the csc_enable bit to SoC config
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Add flexibility by moving the csc_enable bit to SoC specific config

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 40254cd9d168..eb969c5c5c2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -133,6 +133,7 @@ struct mtk_dpi_conf {
 	u32 hvsize_mask;
 	u32 channel_swap_shift;
 	u32 yuv422_en_bit;
+	u32 csc_enable_bit;
 	const struct mtk_dpi_yc_limit *limit;
 };
 
@@ -363,7 +364,8 @@ static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE);
+	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0,
+		     dpi->conf->csc_enable_bit);
 }
 
 static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
@@ -827,6 +829,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -843,6 +846,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -858,6 +862,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
@@ -873,6 +878,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.hvsize_mask = HSIZE_MASK,
 	.channel_swap_shift = CH_SWAP,
 	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
 	.limit = &mtk_dpi_limit,
 };
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
 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      |   4 +-
 6 files changed, 159 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index eb969c5c5c2e..763bfb700135 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,7 @@ struct mtk_dpi {
 	void __iomem *regs;
 	struct device *dev;
 	struct clk *engine_clk;
+	struct clk *dpi_ck_cg;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
 	int irq;
@@ -126,6 +127,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool is_dpintf;
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
@@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 	mtk_dpi_disable(dpi);
 	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->engine_clk);
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+	clk_disable_unprepare(dpi->tvd_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (++dpi->refcount != 1)
 		return 0;
 
+	ret = clk_prepare_enable(dpi->tvd_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+		goto err_pixel;
+	}
+
 	ret = clk_prepare_enable(dpi->engine_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
 		goto err_refcount;
 	}
 
+	ret = clk_prepare_enable(dpi->dpi_ck_cg);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
+		goto err_ck_cg;
+	}
+
 	ret = clk_prepare_enable(dpi->pixel_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
@@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return 0;
 
 err_pixel:
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+err_ck_cg:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
 	dpi->refcount--;
@@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 
 	vm.pixelclock = pll_rate / factor;
 	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
-	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
+		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
-	else
+	} else {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
-
+	}
 
 	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
 
@@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
 	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
-	hsync.sync_width = vm.hsync_len;
-	hsync.back_porch = vm.hback_porch;
-	hsync.front_porch = vm.hfront_porch;
+	if (dpi->conf->is_dpintf) {
+		hsync.sync_width = vm.hsync_len / 4;
+		hsync.back_porch = vm.hback_porch / 4;
+		hsync.front_porch = vm.hfront_porch / 4;
+	} else {
+		hsync.sync_width = vm.hsync_len;
+		hsync.back_porch = vm.hback_porch;
+		hsync.front_porch = vm.hfront_porch;
+	}
 	hsync.shift_half_line = false;
 	vsync_lodd.sync_width = vm.vsync_len;
 	vsync_lodd.back_porch = vm.vback_porch;
@@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
-	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 	mtk_dpi_config_color_format(dpi, dpi->color_format);
-	mtk_dpi_config_2n_h_fre(dpi);
-	mtk_dpi_dual_edge(dpi);
-	mtk_dpi_config_disable_edge(dpi);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
+			     DPINTF_INPUT_2P_EN);
+	} else {
+		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
+		mtk_dpi_config_2n_h_fre(dpi);
+		mtk_dpi_dual_edge(dpi);
+		mtk_dpi_config_disable_edge(dpi);
+	}
 	mtk_dpi_sw_reset(dpi, false);
 
+	mtk_dpi_enable(dpi);
+
 	return 0;
 }
 
@@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 	u32 *input_fmts;
 
 	*num_input_fmts = 0;
-
 	input_fmts = kcalloc(1, sizeof(*input_fmts),
 			     GFP_KERNEL);
 	if (!input_fmts)
@@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
 		if (dpi->conf->num_output_fmts)
 			out_bus_format = dpi->conf->output_fmts[0];
 
-	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
-		bridge_state->input_bus_cfg.format,
-		bridge_state->output_bus_cfg.format);
+	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
+		 bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
 
 	dpi->output_fmt = out_bus_format;
 	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
 	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
 	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
-	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
+	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
+	else
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
 
 	return 0;
 }
@@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
 {
 	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
 
-	if (mode->clock > dpi->conf->max_clock_khz)
+	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
 		return MODE_CLOCK_HIGH;
 
 	return MODE_OK;
@@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
 		return 2;
 }
 
+static unsigned int mt8195_dpintf_calculate_factor(int clock)
+{
+	if (clock < 70000)
+		return 4;
+	else if (clock < 200000)
+		return 2;
+	else
+		return 1;
+}
+
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const u32 mt8195_output_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
 static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.c_bottom = 0x0010,
 	.c_top = 0x0FE0,
@@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.y_top = 0x0FE0,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
+	.c_bottom = 0x0000,
+	.c_top = 0xFFF,
+	.y_bottom = 0x0000,
+	.y_top = 0xFFF,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
@@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.limit = &mtk_dpi_limit,
 };
 
+static const struct mtk_dpi_conf mt8195_dpintf_conf = {
+	.cal_factor = mt8195_dpintf_calculate_factor,
+	.output_fmts = mt8195_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
+	.is_dpintf = true,
+	.dimension_mask = DPINTF_HPW_MASK,
+	.hvsize_mask = DPINTF_HSIZE_MASK,
+	.channel_swap_shift = DPINTF_CH_SWAP,
+	.yuv422_en_bit = DPINTF_YUV422_EN,
+	.csc_enable_bit = DPINTF_CSC_ENABLE,
+	.limit = &mtk_dpintf_limit,
+};
+
 static int mtk_dpi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 	if (IS_ERR(dpi->engine_clk)) {
 		ret = PTR_ERR(dpi->engine_clk);
 		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
+			dev_err(dev, "Failed to get engine clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
 
 		return ret;
 	}
@@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8192-dpi",
 	  .data = &mt8192_conf,
 	},
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = &mt8195_dpintf_conf,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 3a02fabe1662..dd47dd3f2e4f 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,10 +40,15 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+#define DPINTF_YUV422_EN		BIT(24)
+#define DPINTF_CSC_ENABLE		BIT(26)
+#define DPINTF_INPUT_2P_EN		BIT(29)
 
 #define DPI_OUTPUT_SETTING	0x14
 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
 #define SWAP_RGB			0x00
 #define SWAP_GBR			0x01
 #define SWAP_BRG			0x02
@@ -80,8 +85,10 @@
 #define DPI_SIZE		0x18
 #define HSIZE				0
 #define HSIZE_MASK			(0x1FFF << 0)
+#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
 #define VSIZE				16
 #define VSIZE_MASK			(0x1FFF << 16)
+#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
 
 #define DPI_DDR_SETTING		0x1C
 #define DDR_EN				BIT(0)
@@ -93,24 +100,30 @@
 #define DPI_TGEN_HWIDTH		0x20
 #define HPW				0
 #define HPW_MASK			(0xFFF << 0)
+#define DPINTF_HPW_MASK			(0xFFFF << 0)
 
 #define DPI_TGEN_HPORCH		0x24
 #define HBP				0
 #define HBP_MASK			(0xFFF << 0)
+#define DPINTF_HBP_MASK			(0xFFFF << 0)
 #define HFP				16
 #define HFP_MASK			(0xFFF << 16)
+#define DPINTF_HFP_MASK			(0xFFFF << 16)
 
 #define DPI_TGEN_VWIDTH		0x28
 #define DPI_TGEN_VPORCH		0x2C
 
 #define VSYNC_WIDTH_SHIFT		0
 #define VSYNC_WIDTH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
 #define VSYNC_HALF_LINE_SHIFT		16
 #define VSYNC_HALF_LINE_MASK		BIT(16)
 #define VSYNC_BACK_PORCH_SHIFT		0
 #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
 #define VSYNC_FRONT_PORCH_SHIFT		16
 #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
+#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
 
 #define DPI_BG_HCNTL		0x30
 #define BG_RIGHT			(0x1FFF << 0)
@@ -217,4 +230,26 @@
 
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
+
+#define RGB_TO_JPEG			0x00
+#define RGB_TO_FULL709			0x01
+#define RGB_TO_BT601			0x02
+#define RGB_TO_BT709			0x03
+#define JPEG_TO_RGB			0x04
+#define FULL709_TO_RGB			0x05
+#define BT601_TO_RGB			0x06
+#define BT709_TO_RGB			0x07
+#define JPEG_TO_BT601			0x08
+#define JPEG_TO_BT709			0x09
+#define BT601_TO_JPEG			0xA
+#define BT709_TO_JPEG			0xB
+#define BT709_TO_BT601			0xC
+#define BT601_TO_BT709			0xD
+#define JPEG_TO_CERGB			0x14
+#define FULL709_TO_CERGB		0x15
+#define BT601_TO_CERGB			0x16
+#define BT709_TO_CERGB			0x17
+#define RGB_TO_CERGB			0x1C
+#define MATRIX_BIT			BIT(8)
+#define EXT_MATRIX_EN			BIT(12)
 #endif /* __MTK_DPI_REGS_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 245d0074e12d..3738665a712e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
 	[MTK_DSI] = "dsi",
+	[MTK_DP_INTF] = "dp-intf",
+	[MTK_DISP_PWM] = "pwm",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
+	[MTK_DISP_BLS] = "bls",
 };
 
 struct mtk_ddp_comp_match {
@@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
 	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
 	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
+	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
+	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },
 	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
@@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
+	    type == MTK_DP_INTF ||
 	    type == MTK_DSI)
 		return 0;
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 825d763d2378..c4e683f46a95 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_UFOE,
 	MTK_DISP_WDMA,
 	MTK_DPI,
+	MTK_DP_INTF,
 	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a2a783fc580e..e25ac61aac08 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8183-dpi",
 	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = (void *)MTK_DP_INTF },
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8173-dsi",
@@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_OVL_ADAPTOR ||
 		    comp_type == MTK_DISP_RDMA ||
+		    comp_type == MTK_DSI ||
 		    comp_type == MTK_DPI ||
-		    comp_type == MTK_DSI) {
+		    comp_type == MTK_DP_INTF) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, component_compare_of,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 3e998bfb795a..e4b84c347201 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
-	DDP_COMPONENT_DP_INTF0,
-	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
 	DDP_COMPONENT_DSC0,
 	DDP_COMPONENT_DSC1,
+	DDP_COMPONENT_DP_INTF0,
+	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
 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      |   4 +-
 6 files changed, 159 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index eb969c5c5c2e..763bfb700135 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,7 @@ struct mtk_dpi {
 	void __iomem *regs;
 	struct device *dev;
 	struct clk *engine_clk;
+	struct clk *dpi_ck_cg;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
 	int irq;
@@ -126,6 +127,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool is_dpintf;
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
@@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 	mtk_dpi_disable(dpi);
 	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->engine_clk);
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+	clk_disable_unprepare(dpi->tvd_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (++dpi->refcount != 1)
 		return 0;
 
+	ret = clk_prepare_enable(dpi->tvd_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+		goto err_pixel;
+	}
+
 	ret = clk_prepare_enable(dpi->engine_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
 		goto err_refcount;
 	}
 
+	ret = clk_prepare_enable(dpi->dpi_ck_cg);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
+		goto err_ck_cg;
+	}
+
 	ret = clk_prepare_enable(dpi->pixel_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
@@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return 0;
 
 err_pixel:
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+err_ck_cg:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
 	dpi->refcount--;
@@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 
 	vm.pixelclock = pll_rate / factor;
 	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
-	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
+		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
-	else
+	} else {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
-
+	}
 
 	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
 
@@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
 	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
-	hsync.sync_width = vm.hsync_len;
-	hsync.back_porch = vm.hback_porch;
-	hsync.front_porch = vm.hfront_porch;
+	if (dpi->conf->is_dpintf) {
+		hsync.sync_width = vm.hsync_len / 4;
+		hsync.back_porch = vm.hback_porch / 4;
+		hsync.front_porch = vm.hfront_porch / 4;
+	} else {
+		hsync.sync_width = vm.hsync_len;
+		hsync.back_porch = vm.hback_porch;
+		hsync.front_porch = vm.hfront_porch;
+	}
 	hsync.shift_half_line = false;
 	vsync_lodd.sync_width = vm.vsync_len;
 	vsync_lodd.back_porch = vm.vback_porch;
@@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
-	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 	mtk_dpi_config_color_format(dpi, dpi->color_format);
-	mtk_dpi_config_2n_h_fre(dpi);
-	mtk_dpi_dual_edge(dpi);
-	mtk_dpi_config_disable_edge(dpi);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
+			     DPINTF_INPUT_2P_EN);
+	} else {
+		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
+		mtk_dpi_config_2n_h_fre(dpi);
+		mtk_dpi_dual_edge(dpi);
+		mtk_dpi_config_disable_edge(dpi);
+	}
 	mtk_dpi_sw_reset(dpi, false);
 
+	mtk_dpi_enable(dpi);
+
 	return 0;
 }
 
@@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 	u32 *input_fmts;
 
 	*num_input_fmts = 0;
-
 	input_fmts = kcalloc(1, sizeof(*input_fmts),
 			     GFP_KERNEL);
 	if (!input_fmts)
@@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
 		if (dpi->conf->num_output_fmts)
 			out_bus_format = dpi->conf->output_fmts[0];
 
-	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
-		bridge_state->input_bus_cfg.format,
-		bridge_state->output_bus_cfg.format);
+	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
+		 bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
 
 	dpi->output_fmt = out_bus_format;
 	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
 	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
 	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
-	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
+	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
+	else
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
 
 	return 0;
 }
@@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
 {
 	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
 
-	if (mode->clock > dpi->conf->max_clock_khz)
+	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
 		return MODE_CLOCK_HIGH;
 
 	return MODE_OK;
@@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
 		return 2;
 }
 
+static unsigned int mt8195_dpintf_calculate_factor(int clock)
+{
+	if (clock < 70000)
+		return 4;
+	else if (clock < 200000)
+		return 2;
+	else
+		return 1;
+}
+
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const u32 mt8195_output_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
 static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.c_bottom = 0x0010,
 	.c_top = 0x0FE0,
@@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.y_top = 0x0FE0,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
+	.c_bottom = 0x0000,
+	.c_top = 0xFFF,
+	.y_bottom = 0x0000,
+	.y_top = 0xFFF,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
@@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.limit = &mtk_dpi_limit,
 };
 
+static const struct mtk_dpi_conf mt8195_dpintf_conf = {
+	.cal_factor = mt8195_dpintf_calculate_factor,
+	.output_fmts = mt8195_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
+	.is_dpintf = true,
+	.dimension_mask = DPINTF_HPW_MASK,
+	.hvsize_mask = DPINTF_HSIZE_MASK,
+	.channel_swap_shift = DPINTF_CH_SWAP,
+	.yuv422_en_bit = DPINTF_YUV422_EN,
+	.csc_enable_bit = DPINTF_CSC_ENABLE,
+	.limit = &mtk_dpintf_limit,
+};
+
 static int mtk_dpi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 	if (IS_ERR(dpi->engine_clk)) {
 		ret = PTR_ERR(dpi->engine_clk);
 		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
+			dev_err(dev, "Failed to get engine clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
 
 		return ret;
 	}
@@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8192-dpi",
 	  .data = &mt8192_conf,
 	},
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = &mt8195_dpintf_conf,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 3a02fabe1662..dd47dd3f2e4f 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,10 +40,15 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+#define DPINTF_YUV422_EN		BIT(24)
+#define DPINTF_CSC_ENABLE		BIT(26)
+#define DPINTF_INPUT_2P_EN		BIT(29)
 
 #define DPI_OUTPUT_SETTING	0x14
 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
 #define SWAP_RGB			0x00
 #define SWAP_GBR			0x01
 #define SWAP_BRG			0x02
@@ -80,8 +85,10 @@
 #define DPI_SIZE		0x18
 #define HSIZE				0
 #define HSIZE_MASK			(0x1FFF << 0)
+#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
 #define VSIZE				16
 #define VSIZE_MASK			(0x1FFF << 16)
+#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
 
 #define DPI_DDR_SETTING		0x1C
 #define DDR_EN				BIT(0)
@@ -93,24 +100,30 @@
 #define DPI_TGEN_HWIDTH		0x20
 #define HPW				0
 #define HPW_MASK			(0xFFF << 0)
+#define DPINTF_HPW_MASK			(0xFFFF << 0)
 
 #define DPI_TGEN_HPORCH		0x24
 #define HBP				0
 #define HBP_MASK			(0xFFF << 0)
+#define DPINTF_HBP_MASK			(0xFFFF << 0)
 #define HFP				16
 #define HFP_MASK			(0xFFF << 16)
+#define DPINTF_HFP_MASK			(0xFFFF << 16)
 
 #define DPI_TGEN_VWIDTH		0x28
 #define DPI_TGEN_VPORCH		0x2C
 
 #define VSYNC_WIDTH_SHIFT		0
 #define VSYNC_WIDTH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
 #define VSYNC_HALF_LINE_SHIFT		16
 #define VSYNC_HALF_LINE_MASK		BIT(16)
 #define VSYNC_BACK_PORCH_SHIFT		0
 #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
 #define VSYNC_FRONT_PORCH_SHIFT		16
 #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
+#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
 
 #define DPI_BG_HCNTL		0x30
 #define BG_RIGHT			(0x1FFF << 0)
@@ -217,4 +230,26 @@
 
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
+
+#define RGB_TO_JPEG			0x00
+#define RGB_TO_FULL709			0x01
+#define RGB_TO_BT601			0x02
+#define RGB_TO_BT709			0x03
+#define JPEG_TO_RGB			0x04
+#define FULL709_TO_RGB			0x05
+#define BT601_TO_RGB			0x06
+#define BT709_TO_RGB			0x07
+#define JPEG_TO_BT601			0x08
+#define JPEG_TO_BT709			0x09
+#define BT601_TO_JPEG			0xA
+#define BT709_TO_JPEG			0xB
+#define BT709_TO_BT601			0xC
+#define BT601_TO_BT709			0xD
+#define JPEG_TO_CERGB			0x14
+#define FULL709_TO_CERGB		0x15
+#define BT601_TO_CERGB			0x16
+#define BT709_TO_CERGB			0x17
+#define RGB_TO_CERGB			0x1C
+#define MATRIX_BIT			BIT(8)
+#define EXT_MATRIX_EN			BIT(12)
 #endif /* __MTK_DPI_REGS_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 245d0074e12d..3738665a712e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
 	[MTK_DSI] = "dsi",
+	[MTK_DP_INTF] = "dp-intf",
+	[MTK_DISP_PWM] = "pwm",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
+	[MTK_DISP_BLS] = "bls",
 };
 
 struct mtk_ddp_comp_match {
@@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
 	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
 	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
+	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
+	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },
 	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
@@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
+	    type == MTK_DP_INTF ||
 	    type == MTK_DSI)
 		return 0;
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 825d763d2378..c4e683f46a95 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_UFOE,
 	MTK_DISP_WDMA,
 	MTK_DPI,
+	MTK_DP_INTF,
 	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a2a783fc580e..e25ac61aac08 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8183-dpi",
 	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = (void *)MTK_DP_INTF },
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8173-dsi",
@@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_OVL_ADAPTOR ||
 		    comp_type == MTK_DISP_RDMA ||
+		    comp_type == MTK_DSI ||
 		    comp_type == MTK_DPI ||
-		    comp_type == MTK_DSI) {
+		    comp_type == MTK_DP_INTF) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, component_compare_of,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 3e998bfb795a..e4b84c347201 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
-	DDP_COMPONENT_DP_INTF0,
-	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
 	DDP_COMPONENT_DSC0,
 	DDP_COMPONENT_DSC1,
+	DDP_COMPONENT_DP_INTF0,
+	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
 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      |   4 +-
 6 files changed, 159 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index eb969c5c5c2e..763bfb700135 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,7 @@ struct mtk_dpi {
 	void __iomem *regs;
 	struct device *dev;
 	struct clk *engine_clk;
+	struct clk *dpi_ck_cg;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
 	int irq;
@@ -126,6 +127,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool is_dpintf;
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
@@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 	mtk_dpi_disable(dpi);
 	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->engine_clk);
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+	clk_disable_unprepare(dpi->tvd_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (++dpi->refcount != 1)
 		return 0;
 
+	ret = clk_prepare_enable(dpi->tvd_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+		goto err_pixel;
+	}
+
 	ret = clk_prepare_enable(dpi->engine_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
 		goto err_refcount;
 	}
 
+	ret = clk_prepare_enable(dpi->dpi_ck_cg);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
+		goto err_ck_cg;
+	}
+
 	ret = clk_prepare_enable(dpi->pixel_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
@@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return 0;
 
 err_pixel:
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+err_ck_cg:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
 	dpi->refcount--;
@@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 
 	vm.pixelclock = pll_rate / factor;
 	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
-	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
+		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
-	else
+	} else {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
-
+	}
 
 	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
 
@@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
 	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
-	hsync.sync_width = vm.hsync_len;
-	hsync.back_porch = vm.hback_porch;
-	hsync.front_porch = vm.hfront_porch;
+	if (dpi->conf->is_dpintf) {
+		hsync.sync_width = vm.hsync_len / 4;
+		hsync.back_porch = vm.hback_porch / 4;
+		hsync.front_porch = vm.hfront_porch / 4;
+	} else {
+		hsync.sync_width = vm.hsync_len;
+		hsync.back_porch = vm.hback_porch;
+		hsync.front_porch = vm.hfront_porch;
+	}
 	hsync.shift_half_line = false;
 	vsync_lodd.sync_width = vm.vsync_len;
 	vsync_lodd.back_porch = vm.vback_porch;
@@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
-	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 	mtk_dpi_config_color_format(dpi, dpi->color_format);
-	mtk_dpi_config_2n_h_fre(dpi);
-	mtk_dpi_dual_edge(dpi);
-	mtk_dpi_config_disable_edge(dpi);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
+			     DPINTF_INPUT_2P_EN);
+	} else {
+		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
+		mtk_dpi_config_2n_h_fre(dpi);
+		mtk_dpi_dual_edge(dpi);
+		mtk_dpi_config_disable_edge(dpi);
+	}
 	mtk_dpi_sw_reset(dpi, false);
 
+	mtk_dpi_enable(dpi);
+
 	return 0;
 }
 
@@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 	u32 *input_fmts;
 
 	*num_input_fmts = 0;
-
 	input_fmts = kcalloc(1, sizeof(*input_fmts),
 			     GFP_KERNEL);
 	if (!input_fmts)
@@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
 		if (dpi->conf->num_output_fmts)
 			out_bus_format = dpi->conf->output_fmts[0];
 
-	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
-		bridge_state->input_bus_cfg.format,
-		bridge_state->output_bus_cfg.format);
+	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
+		 bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
 
 	dpi->output_fmt = out_bus_format;
 	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
 	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
 	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
-	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
+	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
+	else
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
 
 	return 0;
 }
@@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
 {
 	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
 
-	if (mode->clock > dpi->conf->max_clock_khz)
+	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
 		return MODE_CLOCK_HIGH;
 
 	return MODE_OK;
@@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
 		return 2;
 }
 
+static unsigned int mt8195_dpintf_calculate_factor(int clock)
+{
+	if (clock < 70000)
+		return 4;
+	else if (clock < 200000)
+		return 2;
+	else
+		return 1;
+}
+
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const u32 mt8195_output_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
 static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.c_bottom = 0x0010,
 	.c_top = 0x0FE0,
@@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.y_top = 0x0FE0,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
+	.c_bottom = 0x0000,
+	.c_top = 0xFFF,
+	.y_bottom = 0x0000,
+	.y_top = 0xFFF,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
@@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.limit = &mtk_dpi_limit,
 };
 
+static const struct mtk_dpi_conf mt8195_dpintf_conf = {
+	.cal_factor = mt8195_dpintf_calculate_factor,
+	.output_fmts = mt8195_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
+	.is_dpintf = true,
+	.dimension_mask = DPINTF_HPW_MASK,
+	.hvsize_mask = DPINTF_HSIZE_MASK,
+	.channel_swap_shift = DPINTF_CH_SWAP,
+	.yuv422_en_bit = DPINTF_YUV422_EN,
+	.csc_enable_bit = DPINTF_CSC_ENABLE,
+	.limit = &mtk_dpintf_limit,
+};
+
 static int mtk_dpi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 	if (IS_ERR(dpi->engine_clk)) {
 		ret = PTR_ERR(dpi->engine_clk);
 		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
+			dev_err(dev, "Failed to get engine clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
 
 		return ret;
 	}
@@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8192-dpi",
 	  .data = &mt8192_conf,
 	},
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = &mt8195_dpintf_conf,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 3a02fabe1662..dd47dd3f2e4f 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,10 +40,15 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+#define DPINTF_YUV422_EN		BIT(24)
+#define DPINTF_CSC_ENABLE		BIT(26)
+#define DPINTF_INPUT_2P_EN		BIT(29)
 
 #define DPI_OUTPUT_SETTING	0x14
 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
 #define SWAP_RGB			0x00
 #define SWAP_GBR			0x01
 #define SWAP_BRG			0x02
@@ -80,8 +85,10 @@
 #define DPI_SIZE		0x18
 #define HSIZE				0
 #define HSIZE_MASK			(0x1FFF << 0)
+#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
 #define VSIZE				16
 #define VSIZE_MASK			(0x1FFF << 16)
+#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
 
 #define DPI_DDR_SETTING		0x1C
 #define DDR_EN				BIT(0)
@@ -93,24 +100,30 @@
 #define DPI_TGEN_HWIDTH		0x20
 #define HPW				0
 #define HPW_MASK			(0xFFF << 0)
+#define DPINTF_HPW_MASK			(0xFFFF << 0)
 
 #define DPI_TGEN_HPORCH		0x24
 #define HBP				0
 #define HBP_MASK			(0xFFF << 0)
+#define DPINTF_HBP_MASK			(0xFFFF << 0)
 #define HFP				16
 #define HFP_MASK			(0xFFF << 16)
+#define DPINTF_HFP_MASK			(0xFFFF << 16)
 
 #define DPI_TGEN_VWIDTH		0x28
 #define DPI_TGEN_VPORCH		0x2C
 
 #define VSYNC_WIDTH_SHIFT		0
 #define VSYNC_WIDTH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
 #define VSYNC_HALF_LINE_SHIFT		16
 #define VSYNC_HALF_LINE_MASK		BIT(16)
 #define VSYNC_BACK_PORCH_SHIFT		0
 #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
 #define VSYNC_FRONT_PORCH_SHIFT		16
 #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
+#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
 
 #define DPI_BG_HCNTL		0x30
 #define BG_RIGHT			(0x1FFF << 0)
@@ -217,4 +230,26 @@
 
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
+
+#define RGB_TO_JPEG			0x00
+#define RGB_TO_FULL709			0x01
+#define RGB_TO_BT601			0x02
+#define RGB_TO_BT709			0x03
+#define JPEG_TO_RGB			0x04
+#define FULL709_TO_RGB			0x05
+#define BT601_TO_RGB			0x06
+#define BT709_TO_RGB			0x07
+#define JPEG_TO_BT601			0x08
+#define JPEG_TO_BT709			0x09
+#define BT601_TO_JPEG			0xA
+#define BT709_TO_JPEG			0xB
+#define BT709_TO_BT601			0xC
+#define BT601_TO_BT709			0xD
+#define JPEG_TO_CERGB			0x14
+#define FULL709_TO_CERGB		0x15
+#define BT601_TO_CERGB			0x16
+#define BT709_TO_CERGB			0x17
+#define RGB_TO_CERGB			0x1C
+#define MATRIX_BIT			BIT(8)
+#define EXT_MATRIX_EN			BIT(12)
 #endif /* __MTK_DPI_REGS_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 245d0074e12d..3738665a712e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
 	[MTK_DSI] = "dsi",
+	[MTK_DP_INTF] = "dp-intf",
+	[MTK_DISP_PWM] = "pwm",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
+	[MTK_DISP_BLS] = "bls",
 };
 
 struct mtk_ddp_comp_match {
@@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
 	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
 	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
+	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
+	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },
 	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
@@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
+	    type == MTK_DP_INTF ||
 	    type == MTK_DSI)
 		return 0;
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 825d763d2378..c4e683f46a95 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_UFOE,
 	MTK_DISP_WDMA,
 	MTK_DPI,
+	MTK_DP_INTF,
 	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a2a783fc580e..e25ac61aac08 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8183-dpi",
 	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = (void *)MTK_DP_INTF },
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8173-dsi",
@@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_OVL_ADAPTOR ||
 		    comp_type == MTK_DISP_RDMA ||
+		    comp_type == MTK_DSI ||
 		    comp_type == MTK_DPI ||
-		    comp_type == MTK_DSI) {
+		    comp_type == MTK_DP_INTF) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, component_compare_of,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 3e998bfb795a..e4b84c347201 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
-	DDP_COMPONENT_DP_INTF0,
-	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
 	DDP_COMPONENT_DSC0,
 	DDP_COMPONENT_DSC1,
+	DDP_COMPONENT_DP_INTF0,
+	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
 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      |   4 +-
 6 files changed, 159 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index eb969c5c5c2e..763bfb700135 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,7 @@ struct mtk_dpi {
 	void __iomem *regs;
 	struct device *dev;
 	struct clk *engine_clk;
+	struct clk *dpi_ck_cg;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
 	int irq;
@@ -126,6 +127,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool is_dpintf;
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
@@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 	mtk_dpi_disable(dpi);
 	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->engine_clk);
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+	clk_disable_unprepare(dpi->tvd_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (++dpi->refcount != 1)
 		return 0;
 
+	ret = clk_prepare_enable(dpi->tvd_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+		goto err_pixel;
+	}
+
 	ret = clk_prepare_enable(dpi->engine_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
 		goto err_refcount;
 	}
 
+	ret = clk_prepare_enable(dpi->dpi_ck_cg);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
+		goto err_ck_cg;
+	}
+
 	ret = clk_prepare_enable(dpi->pixel_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
@@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return 0;
 
 err_pixel:
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+err_ck_cg:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
 	dpi->refcount--;
@@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 
 	vm.pixelclock = pll_rate / factor;
 	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
-	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
+		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
-	else
+	} else {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
-
+	}
 
 	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
 
@@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
 	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
-	hsync.sync_width = vm.hsync_len;
-	hsync.back_porch = vm.hback_porch;
-	hsync.front_porch = vm.hfront_porch;
+	if (dpi->conf->is_dpintf) {
+		hsync.sync_width = vm.hsync_len / 4;
+		hsync.back_porch = vm.hback_porch / 4;
+		hsync.front_porch = vm.hfront_porch / 4;
+	} else {
+		hsync.sync_width = vm.hsync_len;
+		hsync.back_porch = vm.hback_porch;
+		hsync.front_porch = vm.hfront_porch;
+	}
 	hsync.shift_half_line = false;
 	vsync_lodd.sync_width = vm.vsync_len;
 	vsync_lodd.back_porch = vm.vback_porch;
@@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
-	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 	mtk_dpi_config_color_format(dpi, dpi->color_format);
-	mtk_dpi_config_2n_h_fre(dpi);
-	mtk_dpi_dual_edge(dpi);
-	mtk_dpi_config_disable_edge(dpi);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
+			     DPINTF_INPUT_2P_EN);
+	} else {
+		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
+		mtk_dpi_config_2n_h_fre(dpi);
+		mtk_dpi_dual_edge(dpi);
+		mtk_dpi_config_disable_edge(dpi);
+	}
 	mtk_dpi_sw_reset(dpi, false);
 
+	mtk_dpi_enable(dpi);
+
 	return 0;
 }
 
@@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 	u32 *input_fmts;
 
 	*num_input_fmts = 0;
-
 	input_fmts = kcalloc(1, sizeof(*input_fmts),
 			     GFP_KERNEL);
 	if (!input_fmts)
@@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
 		if (dpi->conf->num_output_fmts)
 			out_bus_format = dpi->conf->output_fmts[0];
 
-	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
-		bridge_state->input_bus_cfg.format,
-		bridge_state->output_bus_cfg.format);
+	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
+		 bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
 
 	dpi->output_fmt = out_bus_format;
 	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
 	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
 	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
-	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
+	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
+	else
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
 
 	return 0;
 }
@@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
 {
 	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
 
-	if (mode->clock > dpi->conf->max_clock_khz)
+	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
 		return MODE_CLOCK_HIGH;
 
 	return MODE_OK;
@@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
 		return 2;
 }
 
+static unsigned int mt8195_dpintf_calculate_factor(int clock)
+{
+	if (clock < 70000)
+		return 4;
+	else if (clock < 200000)
+		return 2;
+	else
+		return 1;
+}
+
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const u32 mt8195_output_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
 static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.c_bottom = 0x0010,
 	.c_top = 0x0FE0,
@@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.y_top = 0x0FE0,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
+	.c_bottom = 0x0000,
+	.c_top = 0xFFF,
+	.y_bottom = 0x0000,
+	.y_top = 0xFFF,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
@@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.limit = &mtk_dpi_limit,
 };
 
+static const struct mtk_dpi_conf mt8195_dpintf_conf = {
+	.cal_factor = mt8195_dpintf_calculate_factor,
+	.output_fmts = mt8195_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
+	.is_dpintf = true,
+	.dimension_mask = DPINTF_HPW_MASK,
+	.hvsize_mask = DPINTF_HSIZE_MASK,
+	.channel_swap_shift = DPINTF_CH_SWAP,
+	.yuv422_en_bit = DPINTF_YUV422_EN,
+	.csc_enable_bit = DPINTF_CSC_ENABLE,
+	.limit = &mtk_dpintf_limit,
+};
+
 static int mtk_dpi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 	if (IS_ERR(dpi->engine_clk)) {
 		ret = PTR_ERR(dpi->engine_clk);
 		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
+			dev_err(dev, "Failed to get engine clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
 
 		return ret;
 	}
@@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8192-dpi",
 	  .data = &mt8192_conf,
 	},
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = &mt8195_dpintf_conf,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 3a02fabe1662..dd47dd3f2e4f 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,10 +40,15 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+#define DPINTF_YUV422_EN		BIT(24)
+#define DPINTF_CSC_ENABLE		BIT(26)
+#define DPINTF_INPUT_2P_EN		BIT(29)
 
 #define DPI_OUTPUT_SETTING	0x14
 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
 #define SWAP_RGB			0x00
 #define SWAP_GBR			0x01
 #define SWAP_BRG			0x02
@@ -80,8 +85,10 @@
 #define DPI_SIZE		0x18
 #define HSIZE				0
 #define HSIZE_MASK			(0x1FFF << 0)
+#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
 #define VSIZE				16
 #define VSIZE_MASK			(0x1FFF << 16)
+#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
 
 #define DPI_DDR_SETTING		0x1C
 #define DDR_EN				BIT(0)
@@ -93,24 +100,30 @@
 #define DPI_TGEN_HWIDTH		0x20
 #define HPW				0
 #define HPW_MASK			(0xFFF << 0)
+#define DPINTF_HPW_MASK			(0xFFFF << 0)
 
 #define DPI_TGEN_HPORCH		0x24
 #define HBP				0
 #define HBP_MASK			(0xFFF << 0)
+#define DPINTF_HBP_MASK			(0xFFFF << 0)
 #define HFP				16
 #define HFP_MASK			(0xFFF << 16)
+#define DPINTF_HFP_MASK			(0xFFFF << 16)
 
 #define DPI_TGEN_VWIDTH		0x28
 #define DPI_TGEN_VPORCH		0x2C
 
 #define VSYNC_WIDTH_SHIFT		0
 #define VSYNC_WIDTH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
 #define VSYNC_HALF_LINE_SHIFT		16
 #define VSYNC_HALF_LINE_MASK		BIT(16)
 #define VSYNC_BACK_PORCH_SHIFT		0
 #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
 #define VSYNC_FRONT_PORCH_SHIFT		16
 #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
+#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
 
 #define DPI_BG_HCNTL		0x30
 #define BG_RIGHT			(0x1FFF << 0)
@@ -217,4 +230,26 @@
 
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
+
+#define RGB_TO_JPEG			0x00
+#define RGB_TO_FULL709			0x01
+#define RGB_TO_BT601			0x02
+#define RGB_TO_BT709			0x03
+#define JPEG_TO_RGB			0x04
+#define FULL709_TO_RGB			0x05
+#define BT601_TO_RGB			0x06
+#define BT709_TO_RGB			0x07
+#define JPEG_TO_BT601			0x08
+#define JPEG_TO_BT709			0x09
+#define BT601_TO_JPEG			0xA
+#define BT709_TO_JPEG			0xB
+#define BT709_TO_BT601			0xC
+#define BT601_TO_BT709			0xD
+#define JPEG_TO_CERGB			0x14
+#define FULL709_TO_CERGB		0x15
+#define BT601_TO_CERGB			0x16
+#define BT709_TO_CERGB			0x17
+#define RGB_TO_CERGB			0x1C
+#define MATRIX_BIT			BIT(8)
+#define EXT_MATRIX_EN			BIT(12)
 #endif /* __MTK_DPI_REGS_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 245d0074e12d..3738665a712e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
 	[MTK_DSI] = "dsi",
+	[MTK_DP_INTF] = "dp-intf",
+	[MTK_DISP_PWM] = "pwm",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
+	[MTK_DISP_BLS] = "bls",
 };
 
 struct mtk_ddp_comp_match {
@@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
 	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
 	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
+	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
+	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },
 	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
@@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
+	    type == MTK_DP_INTF ||
 	    type == MTK_DSI)
 		return 0;
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 825d763d2378..c4e683f46a95 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_UFOE,
 	MTK_DISP_WDMA,
 	MTK_DPI,
+	MTK_DP_INTF,
 	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a2a783fc580e..e25ac61aac08 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8183-dpi",
 	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = (void *)MTK_DP_INTF },
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8173-dsi",
@@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_OVL_ADAPTOR ||
 		    comp_type == MTK_DISP_RDMA ||
+		    comp_type == MTK_DSI ||
 		    comp_type == MTK_DPI ||
-		    comp_type == MTK_DSI) {
+		    comp_type == MTK_DP_INTF) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, component_compare_of,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 3e998bfb795a..e4b84c347201 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
-	DDP_COMPONENT_DP_INTF0,
-	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
 	DDP_COMPONENT_DSC0,
 	DDP_COMPONENT_DSC1,
+	DDP_COMPONENT_DP_INTF0,
+	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
 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      |   4 +-
 6 files changed, 159 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index eb969c5c5c2e..763bfb700135 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,7 @@ struct mtk_dpi {
 	void __iomem *regs;
 	struct device *dev;
 	struct clk *engine_clk;
+	struct clk *dpi_ck_cg;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
 	int irq;
@@ -126,6 +127,7 @@ struct mtk_dpi_conf {
 	const u32 *output_fmts;
 	u32 num_output_fmts;
 	bool is_ck_de_pol;
+	bool is_dpintf;
 	bool swap_input_support;
 	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
 	u32 dimension_mask;
@@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 	mtk_dpi_disable(dpi);
 	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->engine_clk);
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+	clk_disable_unprepare(dpi->tvd_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (++dpi->refcount != 1)
 		return 0;
 
+	ret = clk_prepare_enable(dpi->tvd_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+		goto err_pixel;
+	}
+
 	ret = clk_prepare_enable(dpi->engine_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
 		goto err_refcount;
 	}
 
+	ret = clk_prepare_enable(dpi->dpi_ck_cg);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
+		goto err_ck_cg;
+	}
+
 	ret = clk_prepare_enable(dpi->pixel_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
@@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return 0;
 
 err_pixel:
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+err_ck_cg:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
 	dpi->refcount--;
@@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 
 	vm.pixelclock = pll_rate / factor;
 	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
-	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
+		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
-	else
+	} else {
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
-
+	}
 
 	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
 
@@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
 	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
-	hsync.sync_width = vm.hsync_len;
-	hsync.back_porch = vm.hback_porch;
-	hsync.front_porch = vm.hfront_porch;
+	if (dpi->conf->is_dpintf) {
+		hsync.sync_width = vm.hsync_len / 4;
+		hsync.back_porch = vm.hback_porch / 4;
+		hsync.front_porch = vm.hfront_porch / 4;
+	} else {
+		hsync.sync_width = vm.hsync_len;
+		hsync.back_porch = vm.hback_porch;
+		hsync.front_porch = vm.hfront_porch;
+	}
 	hsync.shift_half_line = false;
 	vsync_lodd.sync_width = vm.vsync_len;
 	vsync_lodd.back_porch = vm.vback_porch;
@@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	mtk_dpi_config_channel_limit(dpi);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
-	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 	mtk_dpi_config_color_format(dpi, dpi->color_format);
-	mtk_dpi_config_2n_h_fre(dpi);
-	mtk_dpi_dual_edge(dpi);
-	mtk_dpi_config_disable_edge(dpi);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
+			     DPINTF_INPUT_2P_EN);
+	} else {
+		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
+		mtk_dpi_config_2n_h_fre(dpi);
+		mtk_dpi_dual_edge(dpi);
+		mtk_dpi_config_disable_edge(dpi);
+	}
 	mtk_dpi_sw_reset(dpi, false);
 
+	mtk_dpi_enable(dpi);
+
 	return 0;
 }
 
@@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 	u32 *input_fmts;
 
 	*num_input_fmts = 0;
-
 	input_fmts = kcalloc(1, sizeof(*input_fmts),
 			     GFP_KERNEL);
 	if (!input_fmts)
@@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
 		if (dpi->conf->num_output_fmts)
 			out_bus_format = dpi->conf->output_fmts[0];
 
-	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
-		bridge_state->input_bus_cfg.format,
-		bridge_state->output_bus_cfg.format);
+	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
+		 bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
 
 	dpi->output_fmt = out_bus_format;
 	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
 	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
 	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
-	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
+	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
+	else
+		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
 
 	return 0;
 }
@@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
 {
 	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
 
-	if (mode->clock > dpi->conf->max_clock_khz)
+	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
 		return MODE_CLOCK_HIGH;
 
 	return MODE_OK;
@@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
 		return 2;
 }
 
+static unsigned int mt8195_dpintf_calculate_factor(int clock)
+{
+	if (clock < 70000)
+		return 4;
+	else if (clock < 200000)
+		return 2;
+	else
+		return 1;
+}
+
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_2X12_BE,
 };
 
+static const u32 mt8195_output_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
 static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.c_bottom = 0x0010,
 	.c_top = 0x0FE0,
@@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
 	.y_top = 0x0FE0,
 };
 
+static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
+	.c_bottom = 0x0000,
+	.c_top = 0xFFF,
+	.y_bottom = 0x0000,
+	.y_top = 0xFFF,
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.cal_factor = mt8173_calculate_factor,
 	.reg_h_fre_con = 0xe0,
@@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.limit = &mtk_dpi_limit,
 };
 
+static const struct mtk_dpi_conf mt8195_dpintf_conf = {
+	.cal_factor = mt8195_dpintf_calculate_factor,
+	.output_fmts = mt8195_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
+	.is_dpintf = true,
+	.dimension_mask = DPINTF_HPW_MASK,
+	.hvsize_mask = DPINTF_HSIZE_MASK,
+	.channel_swap_shift = DPINTF_CH_SWAP,
+	.yuv422_en_bit = DPINTF_YUV422_EN,
+	.csc_enable_bit = DPINTF_CSC_ENABLE,
+	.limit = &mtk_dpintf_limit,
+};
+
 static int mtk_dpi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 	if (IS_ERR(dpi->engine_clk)) {
 		ret = PTR_ERR(dpi->engine_clk);
 		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
+			dev_err(dev, "Failed to get engine clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
 
 		return ret;
 	}
@@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8192-dpi",
 	  .data = &mt8192_conf,
 	},
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = &mt8195_dpintf_conf,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 3a02fabe1662..dd47dd3f2e4f 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,10 +40,15 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+#define DPINTF_YUV422_EN		BIT(24)
+#define DPINTF_CSC_ENABLE		BIT(26)
+#define DPINTF_INPUT_2P_EN		BIT(29)
 
 #define DPI_OUTPUT_SETTING	0x14
 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
 #define SWAP_RGB			0x00
 #define SWAP_GBR			0x01
 #define SWAP_BRG			0x02
@@ -80,8 +85,10 @@
 #define DPI_SIZE		0x18
 #define HSIZE				0
 #define HSIZE_MASK			(0x1FFF << 0)
+#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
 #define VSIZE				16
 #define VSIZE_MASK			(0x1FFF << 16)
+#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
 
 #define DPI_DDR_SETTING		0x1C
 #define DDR_EN				BIT(0)
@@ -93,24 +100,30 @@
 #define DPI_TGEN_HWIDTH		0x20
 #define HPW				0
 #define HPW_MASK			(0xFFF << 0)
+#define DPINTF_HPW_MASK			(0xFFFF << 0)
 
 #define DPI_TGEN_HPORCH		0x24
 #define HBP				0
 #define HBP_MASK			(0xFFF << 0)
+#define DPINTF_HBP_MASK			(0xFFFF << 0)
 #define HFP				16
 #define HFP_MASK			(0xFFF << 16)
+#define DPINTF_HFP_MASK			(0xFFFF << 16)
 
 #define DPI_TGEN_VWIDTH		0x28
 #define DPI_TGEN_VPORCH		0x2C
 
 #define VSYNC_WIDTH_SHIFT		0
 #define VSYNC_WIDTH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
 #define VSYNC_HALF_LINE_SHIFT		16
 #define VSYNC_HALF_LINE_MASK		BIT(16)
 #define VSYNC_BACK_PORCH_SHIFT		0
 #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
 #define VSYNC_FRONT_PORCH_SHIFT		16
 #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
+#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
 
 #define DPI_BG_HCNTL		0x30
 #define BG_RIGHT			(0x1FFF << 0)
@@ -217,4 +230,26 @@
 
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
+
+#define RGB_TO_JPEG			0x00
+#define RGB_TO_FULL709			0x01
+#define RGB_TO_BT601			0x02
+#define RGB_TO_BT709			0x03
+#define JPEG_TO_RGB			0x04
+#define FULL709_TO_RGB			0x05
+#define BT601_TO_RGB			0x06
+#define BT709_TO_RGB			0x07
+#define JPEG_TO_BT601			0x08
+#define JPEG_TO_BT709			0x09
+#define BT601_TO_JPEG			0xA
+#define BT709_TO_JPEG			0xB
+#define BT709_TO_BT601			0xC
+#define BT601_TO_BT709			0xD
+#define JPEG_TO_CERGB			0x14
+#define FULL709_TO_CERGB		0x15
+#define BT601_TO_CERGB			0x16
+#define BT709_TO_CERGB			0x17
+#define RGB_TO_CERGB			0x1C
+#define MATRIX_BIT			BIT(8)
+#define EXT_MATRIX_EN			BIT(12)
 #endif /* __MTK_DPI_REGS_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 245d0074e12d..3738665a712e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
 	[MTK_DSI] = "dsi",
+	[MTK_DP_INTF] = "dp-intf",
+	[MTK_DISP_PWM] = "pwm",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
+	[MTK_DISP_BLS] = "bls",
 };
 
 struct mtk_ddp_comp_match {
@@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
 	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
 	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
+	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
+	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },
 	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
@@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
+	    type == MTK_DP_INTF ||
 	    type == MTK_DSI)
 		return 0;
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 825d763d2378..c4e683f46a95 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_UFOE,
 	MTK_DISP_WDMA,
 	MTK_DPI,
+	MTK_DP_INTF,
 	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a2a783fc580e..e25ac61aac08 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8183-dpi",
 	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = (void *)MTK_DP_INTF },
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8173-dsi",
@@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_OVL_ADAPTOR ||
 		    comp_type == MTK_DISP_RDMA ||
+		    comp_type == MTK_DSI ||
 		    comp_type == MTK_DPI ||
-		    comp_type == MTK_DSI) {
+		    comp_type == MTK_DP_INTF) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, component_compare_of,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 3e998bfb795a..e4b84c347201 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
-	DDP_COMPONENT_DP_INTF0,
-	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
 	DDP_COMPONENT_DSC0,
 	DDP_COMPONENT_DSC1,
+	DDP_COMPONENT_DP_INTF0,
+	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 15/21] drm/mediatek: dpi: Only enable dpi after the bridge is enabled
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Enabling the dpi too early causes glitches on screen.

Move the call to mtk_dpi_enable() at the end of the bridge_enable
callback to ensure everything is setup properly before enabling dpi.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 763bfb700135..a6b6d62a17e7 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -478,7 +478,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (dpi->pinctrl && dpi->pins_dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
-	mtk_dpi_enable(dpi);
 	return 0;
 
 err_pixel:
@@ -711,6 +710,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
 
 	mtk_dpi_power_on(dpi);
 	mtk_dpi_set_display_mode(dpi, &dpi->mode);
+	mtk_dpi_enable(dpi);
 }
 
 static enum drm_mode_status
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 15/21] drm/mediatek: dpi: Only enable dpi after the bridge is enabled
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

Enabling the dpi too early causes glitches on screen.

Move the call to mtk_dpi_enable() at the end of the bridge_enable
callback to ensure everything is setup properly before enabling dpi.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 763bfb700135..a6b6d62a17e7 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -478,7 +478,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (dpi->pinctrl && dpi->pins_dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
-	mtk_dpi_enable(dpi);
 	return 0;
 
 err_pixel:
@@ -711,6 +710,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
 
 	mtk_dpi_power_on(dpi);
 	mtk_dpi_set_display_mode(dpi, &dpi->mode);
+	mtk_dpi_enable(dpi);
 }
 
 static enum drm_mode_status
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 15/21] drm/mediatek: dpi: Only enable dpi after the bridge is enabled
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Enabling the dpi too early causes glitches on screen.

Move the call to mtk_dpi_enable() at the end of the bridge_enable
callback to ensure everything is setup properly before enabling dpi.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 763bfb700135..a6b6d62a17e7 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -478,7 +478,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (dpi->pinctrl && dpi->pins_dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
-	mtk_dpi_enable(dpi);
 	return 0;
 
 err_pixel:
@@ -711,6 +710,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
 
 	mtk_dpi_power_on(dpi);
 	mtk_dpi_set_display_mode(dpi, &dpi->mode);
+	mtk_dpi_enable(dpi);
 }
 
 static enum drm_mode_status
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 15/21] drm/mediatek: dpi: Only enable dpi after the bridge is enabled
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Enabling the dpi too early causes glitches on screen.

Move the call to mtk_dpi_enable() at the end of the bridge_enable
callback to ensure everything is setup properly before enabling dpi.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 763bfb700135..a6b6d62a17e7 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -478,7 +478,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (dpi->pinctrl && dpi->pins_dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
-	mtk_dpi_enable(dpi);
 	return 0;
 
 err_pixel:
@@ -711,6 +710,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
 
 	mtk_dpi_power_on(dpi);
 	mtk_dpi_set_display_mode(dpi, &dpi->mode);
+	mtk_dpi_enable(dpi);
 }
 
 static enum drm_mode_status
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 15/21] drm/mediatek: dpi: Only enable dpi after the bridge is enabled
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Enabling the dpi too early causes glitches on screen.

Move the call to mtk_dpi_enable() at the end of the bridge_enable
callback to ensure everything is setup properly before enabling dpi.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 763bfb700135..a6b6d62a17e7 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -478,7 +478,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	if (dpi->pinctrl && dpi->pins_dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
-	mtk_dpi_enable(dpi);
 	return 0;
 
 err_pixel:
@@ -711,6 +710,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
 
 	mtk_dpi_power_on(dpi);
 	mtk_dpi_set_display_mode(dpi, &dpi->mode);
+	mtk_dpi_enable(dpi);
 }
 
 static enum drm_mode_status
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 16/21] drm/meditek: dpi: Add matrix_sel helper
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Add a mtk_dpi_matrix_sel() helper to update the DPI_MATRIX_SET
register depending on the color format.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 21 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index a6b6d62a17e7..5b88a7ed5845 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -386,6 +386,25 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
 		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
 }
 
+static void mtk_dpi_matrix_sel(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format)
+{
+	u32 matrix_sel = 0;
+
+	switch (format) {
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL:
+	case MTK_DPI_COLOR_FORMAT_XV_YCC:
+		if (dpi->mode.hdisplay <= 720)
+			matrix_sel = 0x2;
+		break;
+	default:
+		break;
+	}
+	mtk_dpi_mask(dpi, DPI_MATRIX_SET, matrix_sel, INT_MATRIX_SEL_MASK);
+}
+
 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 					enum mtk_dpi_out_color_format format)
 {
@@ -393,6 +412,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
@@ -400,6 +420,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index dd47dd3f2e4f..91b32dfffced 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -231,6 +231,9 @@
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
 
+#define DPI_MATRIX_SET	0xB4
+#define INT_MATRIX_SEL			BIT(0)
+#define INT_MATRIX_SEL_MASK		(0x1F << 0)
 #define RGB_TO_JPEG			0x00
 #define RGB_TO_FULL709			0x01
 #define RGB_TO_BT601			0x02
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 16/21] drm/meditek: dpi: Add matrix_sel helper
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

Add a mtk_dpi_matrix_sel() helper to update the DPI_MATRIX_SET
register depending on the color format.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 21 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index a6b6d62a17e7..5b88a7ed5845 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -386,6 +386,25 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
 		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
 }
 
+static void mtk_dpi_matrix_sel(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format)
+{
+	u32 matrix_sel = 0;
+
+	switch (format) {
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL:
+	case MTK_DPI_COLOR_FORMAT_XV_YCC:
+		if (dpi->mode.hdisplay <= 720)
+			matrix_sel = 0x2;
+		break;
+	default:
+		break;
+	}
+	mtk_dpi_mask(dpi, DPI_MATRIX_SET, matrix_sel, INT_MATRIX_SEL_MASK);
+}
+
 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 					enum mtk_dpi_out_color_format format)
 {
@@ -393,6 +412,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
@@ -400,6 +420,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index dd47dd3f2e4f..91b32dfffced 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -231,6 +231,9 @@
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
 
+#define DPI_MATRIX_SET	0xB4
+#define INT_MATRIX_SEL			BIT(0)
+#define INT_MATRIX_SEL_MASK		(0x1F << 0)
 #define RGB_TO_JPEG			0x00
 #define RGB_TO_FULL709			0x01
 #define RGB_TO_BT601			0x02
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 16/21] drm/meditek: dpi: Add matrix_sel helper
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Add a mtk_dpi_matrix_sel() helper to update the DPI_MATRIX_SET
register depending on the color format.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 21 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index a6b6d62a17e7..5b88a7ed5845 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -386,6 +386,25 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
 		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
 }
 
+static void mtk_dpi_matrix_sel(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format)
+{
+	u32 matrix_sel = 0;
+
+	switch (format) {
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL:
+	case MTK_DPI_COLOR_FORMAT_XV_YCC:
+		if (dpi->mode.hdisplay <= 720)
+			matrix_sel = 0x2;
+		break;
+	default:
+		break;
+	}
+	mtk_dpi_mask(dpi, DPI_MATRIX_SET, matrix_sel, INT_MATRIX_SEL_MASK);
+}
+
 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 					enum mtk_dpi_out_color_format format)
 {
@@ -393,6 +412,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
@@ -400,6 +420,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index dd47dd3f2e4f..91b32dfffced 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -231,6 +231,9 @@
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
 
+#define DPI_MATRIX_SET	0xB4
+#define INT_MATRIX_SEL			BIT(0)
+#define INT_MATRIX_SEL_MASK		(0x1F << 0)
 #define RGB_TO_JPEG			0x00
 #define RGB_TO_FULL709			0x01
 #define RGB_TO_BT601			0x02
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 16/21] drm/meditek: dpi: Add matrix_sel helper
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Add a mtk_dpi_matrix_sel() helper to update the DPI_MATRIX_SET
register depending on the color format.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 21 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index a6b6d62a17e7..5b88a7ed5845 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -386,6 +386,25 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
 		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
 }
 
+static void mtk_dpi_matrix_sel(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format)
+{
+	u32 matrix_sel = 0;
+
+	switch (format) {
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL:
+	case MTK_DPI_COLOR_FORMAT_XV_YCC:
+		if (dpi->mode.hdisplay <= 720)
+			matrix_sel = 0x2;
+		break;
+	default:
+		break;
+	}
+	mtk_dpi_mask(dpi, DPI_MATRIX_SET, matrix_sel, INT_MATRIX_SEL_MASK);
+}
+
 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 					enum mtk_dpi_out_color_format format)
 {
@@ -393,6 +412,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
@@ -400,6 +420,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index dd47dd3f2e4f..91b32dfffced 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -231,6 +231,9 @@
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
 
+#define DPI_MATRIX_SET	0xB4
+#define INT_MATRIX_SEL			BIT(0)
+#define INT_MATRIX_SEL_MASK		(0x1F << 0)
 #define RGB_TO_JPEG			0x00
 #define RGB_TO_FULL709			0x01
 #define RGB_TO_BT601			0x02
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 16/21] drm/meditek: dpi: Add matrix_sel helper
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Add a mtk_dpi_matrix_sel() helper to update the DPI_MATRIX_SET
register depending on the color format.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 21 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index a6b6d62a17e7..5b88a7ed5845 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -386,6 +386,25 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
 		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
 }
 
+static void mtk_dpi_matrix_sel(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format)
+{
+	u32 matrix_sel = 0;
+
+	switch (format) {
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444:
+	case MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL:
+	case MTK_DPI_COLOR_FORMAT_XV_YCC:
+		if (dpi->mode.hdisplay <= 720)
+			matrix_sel = 0x2;
+		break;
+	default:
+		break;
+	}
+	mtk_dpi_mask(dpi, DPI_MATRIX_SET, matrix_sel, INT_MATRIX_SEL_MASK);
+}
+
 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 					enum mtk_dpi_out_color_format format)
 {
@@ -393,6 +412,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, false);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
@@ -400,6 +420,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
 		mtk_dpi_config_csc_enable(dpi, true);
+		mtk_dpi_matrix_sel(dpi, format);
 		if (dpi->conf->swap_input_support)
 			mtk_dpi_config_swap_input(dpi, true);
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index dd47dd3f2e4f..91b32dfffced 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -231,6 +231,9 @@
 #define EDGE_SEL_EN			BIT(5)
 #define H_FRE_2N			BIT(25)
 
+#define DPI_MATRIX_SET	0xB4
+#define INT_MATRIX_SEL			BIT(0)
+#define INT_MATRIX_SEL_MASK		(0x1F << 0)
 #define RGB_TO_JPEG			0x00
 #define RGB_TO_FULL709			0x01
 #define RGB_TO_BT601			0x02
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 MAINTAINERS                       |   1 +
 drivers/phy/mediatek/Kconfig      |   8 ++
 drivers/phy/mediatek/Makefile     |   1 +
 drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4cc47b2dbdc9..bfca96469d80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek DisplayPort PHY driver
+ *
+ * Copyright (c) 2021 BayLibre
+ * Author: Markus Schneider-Pargmann <msp@baylibre.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define PHY_OFFSET 0x1000
+
+#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
+#define TPLL_SSC_EN					BIT(3)
+
+#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
+#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 + 0x38)
+#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
+#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)
+#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
+#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
+#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
+#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
+#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)
+#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
+#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
+#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
+#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
+#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
+#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
+#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
+#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
+#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
+#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
+
+struct mtk_dp_phy {
+	struct regmap *regs;
+};
+
+static int mtk_dp_phy_init(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 driving_params[] = {
+		DRIVING_PARAM_3_DEFAULT,
+		DRIVING_PARAM_4_DEFAULT,
+		DRIVING_PARAM_5_DEFAULT,
+		DRIVING_PARAM_6_DEFAULT,
+		DRIVING_PARAM_7_DEFAULT,
+		DRIVING_PARAM_8_DEFAULT
+	};
+
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+
+	return 0;
+}
+
+static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 val;
+
+	if (opts->dp.set_rate) {
+		switch (opts->dp.link_rate) {
+		default:
+			dev_err(&phy->dev,
+				"Implementation error, unknown linkrate %x\n",
+				opts->dp.link_rate);
+			return -EINVAL;
+		case 1620:
+			val = BIT_RATE_RBR;
+			break;
+		case 2700:
+			val = BIT_RATE_HBR;
+			break;
+		case 5400:
+			val = BIT_RATE_HBR2;
+			break;
+		case 8100:
+			val = BIT_RATE_HBR3;
+			break;
+		}
+		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
+	}
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
+			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
+
+	return 0;
+}
+
+static int mtk_dp_phy_reset(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 0);
+	usleep_range(50, 200);
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 1);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_dp_phy_dev_ops = {
+	.init = mtk_dp_phy_init,
+	.configure = mtk_dp_phy_configure,
+	.reset = mtk_dp_phy_reset,
+	.owner = THIS_MODULE,
+};
+
+static int mtk_dp_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_dp_phy *dp_phy;
+	struct phy *phy;
+	struct regmap *regs;
+
+	regs = *(struct regmap **)dev->platform_data;
+	if (!regs)
+		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
+
+	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
+	if (!dp_phy)
+		return -ENOMEM;
+
+	dp_phy->regs = regs;
+	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
+
+	phy_set_drvdata(phy, dp_phy);
+	if (!dev->of_node)
+		phy_create_lookup(phy, "dp", dev_name(dev));
+
+	return 0;
+}
+
+struct platform_driver mtk_dp_phy_driver = {
+	.probe = mtk_dp_phy_probe,
+	.driver = {
+		.name = "mediatek-dp-phy",
+	},
+};
+module_platform_driver(mtk_dp_phy_driver);
+
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DP PHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 MAINTAINERS                       |   1 +
 drivers/phy/mediatek/Kconfig      |   8 ++
 drivers/phy/mediatek/Makefile     |   1 +
 drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4cc47b2dbdc9..bfca96469d80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek DisplayPort PHY driver
+ *
+ * Copyright (c) 2021 BayLibre
+ * Author: Markus Schneider-Pargmann <msp@baylibre.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define PHY_OFFSET 0x1000
+
+#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
+#define TPLL_SSC_EN					BIT(3)
+
+#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
+#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 + 0x38)
+#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
+#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)
+#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
+#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
+#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
+#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
+#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)
+#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
+#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
+#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
+#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
+#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
+#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
+#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
+#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
+#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
+#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
+
+struct mtk_dp_phy {
+	struct regmap *regs;
+};
+
+static int mtk_dp_phy_init(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 driving_params[] = {
+		DRIVING_PARAM_3_DEFAULT,
+		DRIVING_PARAM_4_DEFAULT,
+		DRIVING_PARAM_5_DEFAULT,
+		DRIVING_PARAM_6_DEFAULT,
+		DRIVING_PARAM_7_DEFAULT,
+		DRIVING_PARAM_8_DEFAULT
+	};
+
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+
+	return 0;
+}
+
+static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 val;
+
+	if (opts->dp.set_rate) {
+		switch (opts->dp.link_rate) {
+		default:
+			dev_err(&phy->dev,
+				"Implementation error, unknown linkrate %x\n",
+				opts->dp.link_rate);
+			return -EINVAL;
+		case 1620:
+			val = BIT_RATE_RBR;
+			break;
+		case 2700:
+			val = BIT_RATE_HBR;
+			break;
+		case 5400:
+			val = BIT_RATE_HBR2;
+			break;
+		case 8100:
+			val = BIT_RATE_HBR3;
+			break;
+		}
+		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
+	}
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
+			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
+
+	return 0;
+}
+
+static int mtk_dp_phy_reset(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 0);
+	usleep_range(50, 200);
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 1);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_dp_phy_dev_ops = {
+	.init = mtk_dp_phy_init,
+	.configure = mtk_dp_phy_configure,
+	.reset = mtk_dp_phy_reset,
+	.owner = THIS_MODULE,
+};
+
+static int mtk_dp_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_dp_phy *dp_phy;
+	struct phy *phy;
+	struct regmap *regs;
+
+	regs = *(struct regmap **)dev->platform_data;
+	if (!regs)
+		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
+
+	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
+	if (!dp_phy)
+		return -ENOMEM;
+
+	dp_phy->regs = regs;
+	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
+
+	phy_set_drvdata(phy, dp_phy);
+	if (!dev->of_node)
+		phy_create_lookup(phy, "dp", dev_name(dev));
+
+	return 0;
+}
+
+struct platform_driver mtk_dp_phy_driver = {
+	.probe = mtk_dp_phy_probe,
+	.driver = {
+		.name = "mediatek-dp-phy",
+	},
+};
+module_platform_driver(mtk_dp_phy_driver);
+
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DP PHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 MAINTAINERS                       |   1 +
 drivers/phy/mediatek/Kconfig      |   8 ++
 drivers/phy/mediatek/Makefile     |   1 +
 drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4cc47b2dbdc9..bfca96469d80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek DisplayPort PHY driver
+ *
+ * Copyright (c) 2021 BayLibre
+ * Author: Markus Schneider-Pargmann <msp@baylibre.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define PHY_OFFSET 0x1000
+
+#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
+#define TPLL_SSC_EN					BIT(3)
+
+#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
+#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 + 0x38)
+#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
+#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)
+#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
+#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
+#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
+#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
+#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)
+#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
+#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
+#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
+#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
+#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
+#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
+#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
+#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
+#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
+#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
+
+struct mtk_dp_phy {
+	struct regmap *regs;
+};
+
+static int mtk_dp_phy_init(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 driving_params[] = {
+		DRIVING_PARAM_3_DEFAULT,
+		DRIVING_PARAM_4_DEFAULT,
+		DRIVING_PARAM_5_DEFAULT,
+		DRIVING_PARAM_6_DEFAULT,
+		DRIVING_PARAM_7_DEFAULT,
+		DRIVING_PARAM_8_DEFAULT
+	};
+
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+
+	return 0;
+}
+
+static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 val;
+
+	if (opts->dp.set_rate) {
+		switch (opts->dp.link_rate) {
+		default:
+			dev_err(&phy->dev,
+				"Implementation error, unknown linkrate %x\n",
+				opts->dp.link_rate);
+			return -EINVAL;
+		case 1620:
+			val = BIT_RATE_RBR;
+			break;
+		case 2700:
+			val = BIT_RATE_HBR;
+			break;
+		case 5400:
+			val = BIT_RATE_HBR2;
+			break;
+		case 8100:
+			val = BIT_RATE_HBR3;
+			break;
+		}
+		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
+	}
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
+			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
+
+	return 0;
+}
+
+static int mtk_dp_phy_reset(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 0);
+	usleep_range(50, 200);
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 1);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_dp_phy_dev_ops = {
+	.init = mtk_dp_phy_init,
+	.configure = mtk_dp_phy_configure,
+	.reset = mtk_dp_phy_reset,
+	.owner = THIS_MODULE,
+};
+
+static int mtk_dp_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_dp_phy *dp_phy;
+	struct phy *phy;
+	struct regmap *regs;
+
+	regs = *(struct regmap **)dev->platform_data;
+	if (!regs)
+		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
+
+	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
+	if (!dp_phy)
+		return -ENOMEM;
+
+	dp_phy->regs = regs;
+	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
+
+	phy_set_drvdata(phy, dp_phy);
+	if (!dev->of_node)
+		phy_create_lookup(phy, "dp", dev_name(dev));
+
+	return 0;
+}
+
+struct platform_driver mtk_dp_phy_driver = {
+	.probe = mtk_dp_phy_probe,
+	.driver = {
+		.name = "mediatek-dp-phy",
+	},
+};
+module_platform_driver(mtk_dp_phy_driver);
+
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DP PHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 MAINTAINERS                       |   1 +
 drivers/phy/mediatek/Kconfig      |   8 ++
 drivers/phy/mediatek/Makefile     |   1 +
 drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4cc47b2dbdc9..bfca96469d80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek DisplayPort PHY driver
+ *
+ * Copyright (c) 2021 BayLibre
+ * Author: Markus Schneider-Pargmann <msp@baylibre.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define PHY_OFFSET 0x1000
+
+#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
+#define TPLL_SSC_EN					BIT(3)
+
+#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
+#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 + 0x38)
+#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
+#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)
+#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
+#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
+#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
+#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
+#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)
+#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
+#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
+#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
+#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
+#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
+#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
+#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
+#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
+#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
+#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
+
+struct mtk_dp_phy {
+	struct regmap *regs;
+};
+
+static int mtk_dp_phy_init(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 driving_params[] = {
+		DRIVING_PARAM_3_DEFAULT,
+		DRIVING_PARAM_4_DEFAULT,
+		DRIVING_PARAM_5_DEFAULT,
+		DRIVING_PARAM_6_DEFAULT,
+		DRIVING_PARAM_7_DEFAULT,
+		DRIVING_PARAM_8_DEFAULT
+	};
+
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+
+	return 0;
+}
+
+static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 val;
+
+	if (opts->dp.set_rate) {
+		switch (opts->dp.link_rate) {
+		default:
+			dev_err(&phy->dev,
+				"Implementation error, unknown linkrate %x\n",
+				opts->dp.link_rate);
+			return -EINVAL;
+		case 1620:
+			val = BIT_RATE_RBR;
+			break;
+		case 2700:
+			val = BIT_RATE_HBR;
+			break;
+		case 5400:
+			val = BIT_RATE_HBR2;
+			break;
+		case 8100:
+			val = BIT_RATE_HBR3;
+			break;
+		}
+		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
+	}
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
+			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
+
+	return 0;
+}
+
+static int mtk_dp_phy_reset(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 0);
+	usleep_range(50, 200);
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 1);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_dp_phy_dev_ops = {
+	.init = mtk_dp_phy_init,
+	.configure = mtk_dp_phy_configure,
+	.reset = mtk_dp_phy_reset,
+	.owner = THIS_MODULE,
+};
+
+static int mtk_dp_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_dp_phy *dp_phy;
+	struct phy *phy;
+	struct regmap *regs;
+
+	regs = *(struct regmap **)dev->platform_data;
+	if (!regs)
+		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
+
+	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
+	if (!dp_phy)
+		return -ENOMEM;
+
+	dp_phy->regs = regs;
+	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
+
+	phy_set_drvdata(phy, dp_phy);
+	if (!dev->of_node)
+		phy_create_lookup(phy, "dp", dev_name(dev));
+
+	return 0;
+}
+
+struct platform_driver mtk_dp_phy_driver = {
+	.probe = mtk_dp_phy_probe,
+	.driver = {
+		.name = "mediatek-dp-phy",
+	},
+};
+module_platform_driver(mtk_dp_phy_driver);
+
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DP PHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

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 <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 MAINTAINERS                       |   1 +
 drivers/phy/mediatek/Kconfig      |   8 ++
 drivers/phy/mediatek/Makefile     |   1 +
 drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4cc47b2dbdc9..bfca96469d80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek DisplayPort PHY driver
+ *
+ * Copyright (c) 2021 BayLibre
+ * Author: Markus Schneider-Pargmann <msp@baylibre.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define PHY_OFFSET 0x1000
+
+#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
+#define TPLL_SSC_EN					BIT(3)
+
+#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
+#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 + 0x38)
+#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
+#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)
+#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
+#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
+#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
+#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
+#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)
+#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
+#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
+#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
+#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
+#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
+#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
+#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
+#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
+#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
+#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
+
+#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
+#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
+#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
+						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
+
+struct mtk_dp_phy {
+	struct regmap *regs;
+};
+
+static int mtk_dp_phy_init(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 driving_params[] = {
+		DRIVING_PARAM_3_DEFAULT,
+		DRIVING_PARAM_4_DEFAULT,
+		DRIVING_PARAM_5_DEFAULT,
+		DRIVING_PARAM_6_DEFAULT,
+		DRIVING_PARAM_7_DEFAULT,
+		DRIVING_PARAM_8_DEFAULT
+	};
+
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
+			  driving_params, ARRAY_SIZE(driving_params));
+
+	return 0;
+}
+
+static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	u32 val;
+
+	if (opts->dp.set_rate) {
+		switch (opts->dp.link_rate) {
+		default:
+			dev_err(&phy->dev,
+				"Implementation error, unknown linkrate %x\n",
+				opts->dp.link_rate);
+			return -EINVAL;
+		case 1620:
+			val = BIT_RATE_RBR;
+			break;
+		case 2700:
+			val = BIT_RATE_HBR;
+			break;
+		case 5400:
+			val = BIT_RATE_HBR2;
+			break;
+		case 8100:
+			val = BIT_RATE_HBR3;
+			break;
+		}
+		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
+	}
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
+			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
+
+	return 0;
+}
+
+static int mtk_dp_phy_reset(struct phy *phy)
+{
+	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 0);
+	usleep_range(50, 200);
+	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, 1);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_dp_phy_dev_ops = {
+	.init = mtk_dp_phy_init,
+	.configure = mtk_dp_phy_configure,
+	.reset = mtk_dp_phy_reset,
+	.owner = THIS_MODULE,
+};
+
+static int mtk_dp_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_dp_phy *dp_phy;
+	struct phy *phy;
+	struct regmap *regs;
+
+	regs = *(struct regmap **)dev->platform_data;
+	if (!regs)
+		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
+
+	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
+	if (!dp_phy)
+		return -ENOMEM;
+
+	dp_phy->regs = regs;
+	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
+
+	phy_set_drvdata(phy, dp_phy);
+	if (!dev->of_node)
+		phy_create_lookup(phy, "dp", dev_name(dev));
+
+	return 0;
+}
+
+struct platform_driver mtk_dp_phy_driver = {
+	.probe = mtk_dp_phy_probe,
+	.driver = {
+		.name = "mediatek-dp-phy",
+	},
+};
+module_platform_driver(mtk_dp_phy_driver);
+
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DP PHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

From: Markus Schneider-Pargmann <msp@baylibre.com>

This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.

It supports the mt8195, the embedded DisplayPort units. It offers
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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/Kconfig       |    8 +
 drivers/gpu/drm/mediatek/Makefile      |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2570 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  570 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |    3 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |    3 +
 6 files changed, 3156 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..a37b6ec9f01e 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -21,6 +21,14 @@ config DRM_MEDIATEK
 	  This driver provides kernel mode setting and
 	  buffer management to userspace.
 
+config DRM_MEDIATEK_DP
+	tristate "DRM DPTX Support for Mediatek SoCs"
+	depends on DRM_MEDIATEK
+	select PHY_MTK_DP
+	select DRM_DP_HELPER
+	help
+	  DRM/KMS Display Port driver for Mediatek SoCs.
+
 config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 3abd27d7c91d..d4d193f60271 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_DRM_MEDIATEK_DP) += 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 000000000000..8eb17ae82bfd
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +-2,2567 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/dp/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/hdmi-codec.h>
+#include <video/videomode.h>
+
+#include "mtk_dp_reg.h"
+
+#define MTK_VDOSYS1_MAX_FRAMERATE 60
+#define MTK_DP_4P1T 4
+#define MTK_DP_HDE 2
+#define MTK_DP_PIX_PER_ADDR 2
+#define MTK_DP_AUX_WAIT_REPLY_COUNT 20
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT 3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT 8
+#define MTK_DP_TRAIN_MAX_ITERATIONS 5
+
+#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_NORMAL,
+	MTK_DP_TRAIN_STATE_DPIDLE,
+};
+
+struct mtk_dp_timings {
+	struct videomode vm;
+
+	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;
+
+	u8  irq_status;
+	int check_cap_count;
+};
+
+/* 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,
+};
+
+//TODO: redundant with DP_MSA_MISC_*_BPC ?
+/* Same values as used for DP Spec MISC0 bits 5,6,7 */
+enum mtk_dp_color_depth {
+	MTK_DP_COLOR_DEPTH_6BIT = 0,
+	MTK_DP_COLOR_DEPTH_8BIT = 1,
+	MTK_DP_COLOR_DEPTH_10BIT = 2,
+	MTK_DP_COLOR_DEPTH_12BIT = 3,
+	MTK_DP_COLOR_DEPTH_16BIT = 4,
+	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
+};
+
+struct mtk_dp_info {
+	enum mtk_dp_color_depth depth;
+	enum dp_pixelformat format;
+	struct mtk_dp_timings timings;
+};
+
+struct dp_cal_data {
+	unsigned int glb_bias_trim;
+	unsigned int clktx_impse;
+
+	unsigned int *ln_tx_impsel_pmos;
+	unsigned int *ln_tx_impsel_nmos;
+};
+
+struct mtk_dp {
+	struct device *dev;
+	struct platform_device *phy_dev;
+	struct phy *phy;
+	struct dp_cal_data cal_data;
+	u8 max_lanes;
+	u8 max_linkrate;
+
+	struct drm_device *drm_dev;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_dp_aux aux;
+
+	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
+
+	struct mtk_dp_info info;
+	enum mtk_dp_state state;
+
+	struct mtk_dp_train_info train_info;
+	enum mtk_dp_train_state train_state;
+	unsigned int input_fmt;
+
+	struct regmap *regs;
+	struct clk *dp_tx_clk;
+
+	bool enabled;
+
+	bool has_fec;
+	/* Protects the mtk_dp struct */
+	struct mutex dp_lock;
+
+	struct drm_connector *conn;
+};
+
+static struct regmap_config mtk_dp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = SEC_OFFSET + 0x90,
+	.name = "mtk-dp-registers",
+};
+
+static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
+{
+	return container_of(b, struct mtk_dp, bridge);
+}
+
+static u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
+{
+	u32 read_val;
+	int ret;
+
+	ret = regmap_read(mtk_dp->regs, offset, &read_val);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to read register 0x%x: %d\n",
+			offset, ret);
+		return 0;
+	}
+
+	return read_val;
+}
+
+static int mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
+{
+	int ret;
+
+	ret = regmap_write(mtk_dp->regs, offset, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to write register 0x%x with value 0x%x: %d\n",
+			offset, val, ret);
+	return ret;
+}
+
+static int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset, u32 val,
+			      u32 mask)
+{
+	int ret;
+
+	ret = regmap_update_bits(mtk_dp->regs, offset, mask, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to update register 0x%x with value 0x%x, mask 0x%x: %d\n",
+			offset, val, mask, ret);
+	return ret;
+}
+
+static int mtk_dp_bulk_16bit_write(struct mtk_dp *mtk_dp, u32 offset, u8 *buf,
+				   size_t length)
+{
+	int i;
+	int ret = 0;
+	int num_regs = (length + 1) / 2;
+
+	/* 2 bytes per register */
+	for (i = 0; i < num_regs; i++) {
+		u32 val = buf[i * 2] |
+			  (i * 2 + 1 < length ? buf[i * 2 + 1] << 8 : 0);
+
+		ret = mtk_dp_write(mtk_dp, offset + i * 4, val);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static unsigned long mtk_dp_sip_atf_call(unsigned int cmd, unsigned int para)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32, cmd, para, 0, 0, 0, 0, 0,
+		      &res);
+
+	pr_debug("[DPTX]%s cmd 0x%x, p1 0x%x, ret 0x%lx-0x%lx", __func__, cmd,
+		 para, res.a0, res.a1);
+	return res.a1;
+}
+
+static int mtk_dp_msa_bypass_disable(struct mtk_dp *mtk_dp)
+{
+	const u16 bits_to_set =
+		BIT(HTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HWIDTH_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VHEIGHT_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSP_SEL_DP_ENC0_P0_SHIFT) | BIT(HSW_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSP_SEL_DP_ENC0_P0_SHIFT) | BIT(VSW_SEL_DP_ENC0_P0_SHIFT);
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3030, bits_to_set,
+			   bits_to_set);
+}
+
+static int mtk_dp_set_msa(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3010, mode.htotal,
+				 HTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3018,
+				 timings->vm.hsync_len + timings->vm.hback_porch,
+			   HSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028,
+				 timings->vm.hsync_len << HSW_SW_DP_ENC0_P0_SHIFT,
+			   HSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028, 0,
+				 HSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3020, timings->vm.hactive,
+				 HWIDTH_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3014, mode.vtotal,
+				 VTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_301C,
+				 timings->vm.vsync_len + timings->vm.vback_porch,
+			   VSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C,
+				 timings->vm.vsync_len << VSW_SW_DP_ENC0_P0_SHIFT,
+			   VSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C, 0,
+				 VSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3024, timings->vm.vactive,
+				 VHEIGHT_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3064, timings->vm.hactive,
+				 HDE_NUM_LAST_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3154, mode.htotal,
+				 PGEN_HTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3158,
+				 timings->vm.hfront_porch,
+			   PGEN_HSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_315C, timings->vm.hsync_len,
+				 PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
+				 timings->vm.hback_porch + timings->vm.hsync_len,
+			   PGEN_HFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3164, timings->vm.hactive,
+				 PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3168, mode.vtotal,
+				 PGEN_VTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_316C,
+				 timings->vm.vfront_porch,
+			   PGEN_VSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3170, timings->vm.vsync_len,
+				 PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
+				 timings->vm.vback_porch + timings->vm.vsync_len,
+			   PGEN_VFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3178, timings->vm.vactive,
+				 PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
+				   enum dp_pixelformat color_format)
+{
+	u32 val;
+	int ret;
+
+	mtk_dp->info.format = color_format;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_format << DP_TEST_COLOR_FORMAT_SHIFT,
+				 DP_TEST_COLOR_FORMAT_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_format) {
+	case DP_PIXELFORMAT_YUV422:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422;
+		break;
+	case DP_PIXELFORMAT_YUV420:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420;
+		break;
+	case DP_PIXELFORMAT_RGB:
+	case DP_PIXELFORMAT_YUV444:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
+		break;
+	case DP_PIXELFORMAT_Y_ONLY:
+	case DP_PIXELFORMAT_RAW:
+	case DP_PIXELFORMAT_RESERVED:
+	default:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
+			 color_format);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_color_depth(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_color_depth color_depth)
+{
+	int ret;
+	u32 val;
+
+	mtk_dp->info.depth = color_depth;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_depth << DP_TEST_BIT_DEPTH_SHIFT,
+				 DP_TEST_BIT_DEPTH_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_depth) {
+	case MTK_DP_COLOR_DEPTH_6BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_8BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_10BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_12BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_16BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_UNKNOWN:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color depth %d\n",
+			 color_depth);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_mn_overwrite_disable(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				  VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_sram_read_start(struct mtk_dp *mtk_dp, u32 val)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				  val << SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT,
+				  SRAM_START_READ_THRD_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_setup_encoder(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				 BIT(VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT),
+				 VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+				 0x20 << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 0x20 << SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3300,
+				 2 << VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT,
+			    VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 4 << FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT,
+			    FIFO_READ_START_POINT_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368,
+			   1 << VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT |
+			   1 << VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT |
+			   BIT(SDP_DP13_EN_DP_ENC1_P0_SHIFT) |
+			   1 << BS2BS_MODE_DP_ENC1_P0_SHIFT);
+
+	return ret;
+}
+
+static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3038, 0,
+				 VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31B0,
+				 4 << PGEN_PATTERN_SEL_SHIFT, PGEN_PATTERN_SEL_MASK);
+
+	return ret;
+}
+
+static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
+{
+	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
+		  HPD_DB_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT));
+	/* Wait for the irq to be cleared */
+	usleep_range(MTK_DP_AUX_WRITE_READ_WAIT_TIME_US,
+		     MTK_DP_AUX_WRITE_READ_WAIT_TIME_US * 2);
+}
+
+static int mtk_dp_aux_set_cmd(struct mtk_dp *mtk_dp, u8 cmd, u32 addr)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3644, cmd,
+				 MCU_REQUEST_COMMAND_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3648, addr,
+				 MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_364C, addr >> 16,
+				 MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_aux_cmd_complete(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+				  BIT(MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT),
+				  MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK |
+				  PHY_FIFO_RST_AUX_TX_P0_MASK |
+				  MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+}
+
+static int mtk_dp_aux_request_ready(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3630,
+				  BIT(AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT),
+				  AUX_TX_REQUEST_READY_AUX_TX_P0_MASK);
+}
+
+static void mtk_dp_aux_fill_write_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				       size_t length)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_AUX_P0_3708, buf, length);
+}
+
+static int mtk_dp_aux_read_rx_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				   size_t length, int read_delay)
+{
+	int ret;
+	int read_pos;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620, 0,
+				 AUX_RD_MODE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+
+	for (read_pos = 0; read_pos < length; read_pos++) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620,
+					 BIT(AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT),
+					 AUX_RX_FIFO_READ_PULSE_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Hardware needs time to update the data */
+		usleep_range(read_delay, read_delay * 2);
+		buf[read_pos] =
+			(u8)(mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3620) &
+			     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK >>
+				     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_set_length(struct mtk_dp *mtk_dp, size_t length)
+{
+	int ret;
+
+	if (length > 0) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+					 (length - 1)
+					 << MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT,
+					 MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C,
+					 BIT(AUX_NO_LENGTH_AUX_TX_P0_SHIFT),
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_wait_for_completion(struct mtk_dp *mtk_dp, bool is_read)
+{
+	int wait_reply = MTK_DP_AUX_WAIT_REPLY_COUNT;
+
+	while (--wait_reply) {
+		u32 aux_irq_status;
+
+		if (is_read) {
+			u32 fifo_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3618);
+
+			if (fifo_status &
+			    (AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK |
+			     AUX_RX_FIFO_FULL_AUX_TX_P0_MASK)) {
+				return 0;
+			}
+		}
+
+		aux_irq_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3640);
+		if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK)
+			return 0;
+
+		if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK)
+			return -ETIMEDOUT;
+
+		/* Give the hardware a chance to reach completion before retrying */
+		usleep_range(100, 500);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
+				  u32 addr, u8 *buf, size_t length)
+{
+	int ret;
+	u32 reply_cmd;
+
+	if (is_read && (length > DP_AUX_MAX_PAYLOAD_BYTES ||
+			(cmd == DP_AUX_NATIVE_READ && !length)))
+		return -EINVAL;
+
+	if (!is_read) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 BIT(AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT),
+					 AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	mtk_dp_aux_set_cmd(mtk_dp, cmd, addr);
+	mtk_dp_aux_set_length(mtk_dp, length);
+
+	if (!is_read) {
+		if (length)
+			mtk_dp_aux_fill_write_fifo(mtk_dp, buf, length);
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_request_ready(mtk_dp);
+
+	ret = mtk_dp_aux_wait_for_completion(mtk_dp, is_read);
+
+	reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
+		    AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
+
+	if (ret || reply_cmd) {
+		u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
+				 AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
+		if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) {
+			drm_err(mtk_dp->drm_dev,
+				"AUX Rx Aux hang, need SW reset\n");
+			return -EIO;
+		}
+
+		mtk_dp_aux_cmd_complete(mtk_dp);
+		mtk_dp_aux_irq_clear(mtk_dp);
+
+		return -ETIMEDOUT;
+	}
+
+	if (!length) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+
+	} else if (is_read) {
+		int read_delay;
+
+		if (cmd == (DP_AUX_I2C_READ | DP_AUX_I2C_MOT) ||
+		    cmd == DP_AUX_I2C_READ)
+			read_delay = 500;
+		else
+			read_delay = 100;
+
+		mtk_dp_aux_read_rx_fifo(mtk_dp, buf, length, read_delay);
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	return 0;
+}
+
+static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
+					  int swing_val, int preemphasis)
+{
+	int ret;
+
+	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
+
+	if (lane_num < 0 || lane_num > 3)
+		return false;
+
+	dev_dbg(mtk_dp->dev,
+		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
+		swing_val, preemphasis);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 swing_val << (DP_TX0_VOLT_SWING_SHIFT + lane_shift),
+				 DP_TX0_VOLT_SWING_MASK << lane_shift);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT + lane_shift),
+				 DP_TX0_PRE_EMPH_MASK << lane_shift);
+
+	return !ret;
+}
+
+static int mtk_dp_reset_swing_pre_emphasis(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP, 0,
+				  DP_TX0_VOLT_SWING_MASK | DP_TX1_VOLT_SWING_MASK |
+				  DP_TX2_VOLT_SWING_MASK |
+				  DP_TX3_VOLT_SWING_MASK |
+				  DP_TX0_PRE_EMPH_MASK | DP_TX1_PRE_EMPH_MASK |
+				  DP_TX2_PRE_EMPH_MASK | DP_TX3_PRE_EMPH_MASK);
+}
+
+static int mtk_dp_fec_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				  enable ? BIT(FEC_EN_DP_TRANS_P0_SHIFT) : 0,
+				  FEC_EN_DP_TRANS_P0_MASK);
+}
+
+static u32 mtk_dp_swirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u32 irq_status = mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_35D0) &
+			 SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, irq_status,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, 0,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+	}
+
+	return irq_status;
+}
+
+static u32 mtk_dp_hwirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u8 irq_status = (mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3418) &
+			 IRQ_STATUS_DP_TRANS_P0_MASK) >>
+			IRQ_STATUS_DP_TRANS_P0_SHIFT;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, irq_status,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, 0,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+	}
+
+	return irq_status;
+}
+
+static int mtk_dp_hwirq_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = enable ? 0 : IRQ_MASK_DP_TRANS_P0_DISC_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_CONN_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_INT_IRQ;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, val,
+			   IRQ_MASK_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_342C,
+				 XTAL_FREQ_DP_TRANS_P0_DEFAULT,
+			   XTAL_FREQ_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				 BIT(FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT),
+			   FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+				 BIT(AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT),
+			   AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_IRQ_MASK, IRQ_MASK_AUX_TOP_IRQ,
+				 IRQ_MASK_AUX_TOP_IRQ);
+
+	return ret;
+}
+
+static void mtk_dp_initialize_hpd_detect_settings(struct mtk_dp *mtk_dp)
+{
+	/* Debounce threshold */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   8 << HPD_DEB_THD_DP_TRANS_P0_SHIFT,
+			   HPD_DEB_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
+			    HPD_INT_THD_DP_TRANS_P0_UPPER_1100US)
+				   << HPD_INT_THD_DP_TRANS_P0_SHIFT,
+			   HPD_INT_THD_DP_TRANS_P0_MASK);
+
+	/* Connect threshold 1.5ms + 5 x 0.1ms = 2ms
+	 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (5 << HPD_DISC_THD_DP_TRANS_P0_SHIFT) |
+				   (5 << HPD_CONN_THD_DP_TRANS_P0_SHIFT),
+			   HPD_DISC_THD_DP_TRANS_P0_MASK |
+				   HPD_CONN_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	/* modify timeout threshold = 1595 [12 : 8] */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_360C, 0x1595,
+				 AUX_TIMEOUT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3658, 0,
+				 AUX_TX_OV_EN_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 25 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3634,
+				 25 << AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT,
+			   AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 13 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3614,
+				 13 << AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT,
+			   AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_37C8,
+				 BIT(MTK_ATOP_EN_AUX_TX_P0_SHIFT),
+			   MTK_ATOP_EN_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 VBID_VIDEO_MUTE_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	mtk_dp_set_color_format(mtk_dp, DP_PIXELFORMAT_RGB);
+	mtk_dp_set_color_depth(mtk_dp, MTK_DP_COLOR_DEPTH_8BIT);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3368,
+				 1 << BS2BS_MODE_DP_ENC1_P0_SHIFT,
+			   BS2BS_MODE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* dp tx encoder reset all sw */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
+				 BIT(DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT),
+			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				 DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_digital_sw_reset(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C,
+				 BIT(DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT),
+			   DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C, 0,
+				 DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_lanes(struct mtk_dp *mtk_dp, int lanes)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35F0,
+				 lanes == 0 ? 0 : BIT(3), BIT(3) | BIT(2));
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, lanes,
+				 LANE_NUM_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4,
+				 lanes << LANE_NUM_DP_TRANS_P0_SHIFT,
+			   LANE_NUM_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int link_rate_to_mb_per_s(struct mtk_dp *mtk_dp,
+				 enum mtk_dp_linkrate linkrate)
+{
+	switch (linkrate) {
+	case MTK_DP_LINKRATE_RBR:
+		return 1620;
+	case MTK_DP_LINKRATE_HBR:
+		return 2700;
+	case MTK_DP_LINKRATE_HBR2:
+		return 5400;
+	case MTK_DP_LINKRATE_HBR3:
+		return 8100;
+	default:
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, unknown linkrate %d\n",
+			linkrate);
+		return -EINVAL;
+	}
+}
+
+static u32 check_cal_data_valid(struct mtk_dp *mtk_dp, u32 min, u32 max, u32 val, u32 default_val)
+{
+	if (val < min || val > max)
+		dev_warn(mtk_dp->dev, "Invalid calibration data: %d (< %d || > %d), returning default %d\n",
+			 val, min, max, default_val);
+		return default_val;
+
+	return val;
+}
+
+static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
+{
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+	struct device *dev = mtk_dp->dev;
+	struct nvmem_cell *cell;
+	u32 *buf;
+	size_t len;
+
+	cell = nvmem_cell_get(dev, "dp_calibration_data");
+	if (IS_ERR(cell)) {
+		dev_err(dev,
+			"Error: Failed to get nvmem cell dp_calibration_data\n");
+		return PTR_ERR(cell);
+	}
+
+	buf = (u32 *)nvmem_cell_read(cell, &len);
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) {
+		dev_err(dev,
+			"Error: Failed to read nvmem_cell_read fail len %ld\n",
+			(len / sizeof(u32)));
+		return PTR_ERR(buf);
+	}
+
+	cal_data->ln_tx_impsel_nmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_nmos)
+		return -ENOMEM;
+
+	cal_data->ln_tx_impsel_pmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_pmos)
+		return -ENOMEM;
+
+	cal_data->glb_bias_trim =
+		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+	cal_data->clktx_impse =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int mtk_dp_set_cal_data(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_DPAUX_TX,
+				 cal_data->clktx_impse << 20, RG_CKM_PT0_CKTX_IMPSEL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_BIAS_GEN_00,
+				 cal_data->glb_bias_trim << 16,
+			   RG_XTP_GLB_BIAS_INTR_CTRL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_pmos[0] << 12,
+			   RG_XTP_LN0_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_nmos[0] << 16,
+			   RG_XTP_LN0_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_pmos[1] << 12,
+			   RG_XTP_LN1_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_nmos[1] << 16,
+			   RG_XTP_LN1_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_pmos[2] << 12,
+			   RG_XTP_LN2_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_nmos[2] << 16,
+			   RG_XTP_LN2_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_pmos[3] << 12,
+			   RG_XTP_LN3_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_nmos[3] << 16,
+			   RG_XTP_LN3_TX_IMPSEL_NMOS);
+
+	return ret;
+}
+
+static int mtk_dp_phy_configure(struct mtk_dp *mtk_dp,
+				enum mtk_dp_linkrate link_rate, int lane_count)
+{
+	int ret;
+	union phy_configure_opts phy_opts = {
+		.dp = {
+			.link_rate = link_rate_to_mb_per_s(mtk_dp, link_rate),
+			.set_rate = 1,
+			.lanes = lane_count,
+			.set_lanes = 1,
+			.ssc = mtk_dp->train_info.sink_ssc,
+		}
+		};
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP,
+				 DP_PWR_STATE_MASK);
+	if (ret)
+		return ret;
+
+	ret = phy_configure(mtk_dp->phy, &phy_opts);
+
+	if (ret)
+		return ret;
+
+	mtk_dp_set_cal_data(mtk_dp);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_idle_pattern(struct mtk_dp *mtk_dp, bool enable)
+{
+	const u32 val = POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK;
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3580, enable ? val : 0, val);
+}
+
+static int mtk_dp_train_set_pattern(struct mtk_dp *mtk_dp, int pattern)
+{
+	int ret;
+
+	if (pattern < 0 || pattern > 4) {
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, no such pattern %d\n", pattern);
+		return -EINVAL;
+	}
+
+	if (pattern == 1) { /* TPS1 */
+		ret = mtk_dp_set_idle_pattern(mtk_dp, false);
+		if (ret)
+			return ret;
+	}
+
+	return mtk_dp_update_bits(mtk_dp,
+			   MTK_DP_TRANS_P0_3400,
+			   pattern ? BIT(pattern - 1) << PATTERN1_EN_DP_TRANS_P0_SHIFT : 0,
+			   PATTERN1_EN_DP_TRANS_P0_MASK | PATTERN2_EN_DP_TRANS_P0_MASK |
+			   PATTERN3_EN_DP_TRANS_P0_MASK |
+			   PATTERN4_EN_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_set_enhanced_frame_mode(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
+			   enable ? BIT(ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT) : 0,
+			   ENHANCED_FRAME_EN_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3404,
+			   enable ? DP_SCR_EN_DP_TRANS_P0_MASK : 0,
+			   DP_SCR_EN_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
+
+	if (enable)
+		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
+			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+}
+
+static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, 0,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	/* Wait for power enable */
+	usleep_range(10, 200);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, SW_RST_B_PHYD,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL,
+			   DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
+			   DA_CKM_CKTX0_EN_FORCE_EN | DA_CKM_BIAS_LPF_EN_FORCE_VAL |
+		     DA_CKM_BIAS_EN_FORCE_VAL |
+		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
+		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
+
+	if (ret)
+		return ret;
+
+	/* Disable RX */
+	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
+			   0x550 | BIT(FUSE_SEL_SHIFT) | BIT(MEM_ISO_EN_SHIFT));
+
+	return ret;
+}
+
+static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
+{
+	mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR2;
+	mtk_dp->train_info.lane_count = mtk_dp->max_lanes;
+	mtk_dp->train_info.irq_status = 0;
+	mtk_dp->train_info.cable_plugged_in = false;
+	mtk_dp->train_info.cable_state_change = false;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	mtk_dp->state = MTK_DP_STATE_INITIAL;
+
+	mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+	mtk_dp->info.depth = MTK_DP_COLOR_DEPTH_8BIT;
+	memset(&mtk_dp->info.timings, 0, sizeof(struct mtk_dp_timings));
+	mtk_dp->info.timings.frame_rate = 60;
+
+	mtk_dp->has_fec = false;
+}
+
+static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
+{
+	u32 sram_read_start = MTK_DP_TBC_BUF_READ_START_ADDR;
+
+	if (mtk_dp->train_info.lane_count > 0) {
+		sram_read_start = min_t(u32,
+					MTK_DP_TBC_BUF_READ_START_ADDR,
+					mtk_dp->info.timings.vm.hactive /
+					mtk_dp->train_info.lane_count /
+					MTK_DP_4P1T / MTK_DP_HDE / MTK_DP_PIX_PER_ADDR);
+		mtk_dp_set_sram_read_start(mtk_dp, sram_read_start);
+	}
+
+	mtk_dp_setup_encoder(mtk_dp);
+}
+
+static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
+{
+	u8 target_frame_rate = 60;
+	u32 target_pixel_clk;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.frame_rate > 0) {
+		target_frame_rate = mtk_dp->info.timings.frame_rate;
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	} else if (mtk_dp->info.timings.pix_rate_khz > 0) {
+		target_pixel_clk = mtk_dp->info.timings.pix_rate_khz * 1000;
+	} else {
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	}
+
+	mtk_dp->info.timings.pix_rate_khz = target_pixel_clk / 1000;
+}
+
+static void mtk_dp_set_tx_out(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_msa_bypass_disable(mtk_dp);
+	mtk_dp_calculate_pixrate(mtk_dp);
+	mtk_dp_pg_disable(mtk_dp);
+	mtk_dp_setup_tu(mtk_dp);
+}
+
+static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
+{
+	ssize_t ret;
+	u8 sink_count;
+	bool locked;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+	u32 sink_count_reg = DP_SINK_COUNT_ESI;
+	u32 link_status_reg = DP_LANE0_1_STATUS;
+
+	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg, &sink_count);
+	if (ret < 0) {
+		drm_err(mtk_dp->drm_dev, "Read sink count failed: %ld\n", ret);
+		return ret;
+	}
+
+	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg, link_status,
+			       sizeof(link_status));
+	if (!ret) {
+		drm_err(mtk_dp->drm_dev, "Read link status failed: %ld\n",
+			ret);
+		return ret;
+	}
+
+	locked = drm_dp_channel_eq_ok(link_status,
+				      mtk_dp->train_info.lane_count);
+	if (!locked && mtk_dp->train_state > MTK_DP_TRAIN_STATE_TRAINING_PRE)
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+
+	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR,
+				   DP_REMOTE_CONTROL_COMMAND_PENDING);
+
+	if (DP_GET_SINK_COUNT(sink_count) &&
+	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
+		mtk_dp->train_info.check_cap_count = 0;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+		msleep(20);
+	}
+
+	return 0;
+}
+
+static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
+					  u8 dpcd_adjust_req[2])
+{
+	int lane;
+
+	for (lane = 0; lane < lanes; ++lane) {
+		u8 val;
+		u8 swing;
+		u8 preemphasis;
+		int index = lane / 2;
+		int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
+
+		swing = (dpcd_adjust_req[index] >> shift) &
+			DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
+		preemphasis = ((dpcd_adjust_req[index] >> shift) &
+			       DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
+			      DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
+		val = swing << DP_TRAIN_VOLTAGE_SWING_SHIFT |
+		      preemphasis << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+		if (swing == DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
+			val |= DP_TRAIN_MAX_SWING_REACHED;
+		if (preemphasis == 3)
+			val |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+		mtk_dp_set_swing_pre_emphasis(mtk_dp, lane, swing, preemphasis);
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_LANE0_SET + lane,
+				   val);
+	}
+}
+
+static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
+				    u8 link_status[DP_LINK_STATUS_SIZE])
+{
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
+			 DP_LINK_STATUS_SIZE);
+}
+
+static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
+			      u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, false);
+	if (ret)
+		return ret;
+
+	if (*status_control == 0) {
+		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
+		if (ret)
+			return ret;
+
+		val = DP_LINK_SCRAMBLING_DISABLE |
+			DP_TRAINING_PATTERN_1;
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_1);
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 1;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
+					       mtk_dp->rx_cap);
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (drm_dp_clock_recovery_ok(link_status,
+				     target_lane_count)) {
+		mtk_dp->train_info.cr_done = true;
+		*iteration_count = 1;
+		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
+		return 0;
+	} else if (*prev_lane_adjust == link_status[4]) {
+		(*iteration_count)++;
+		if (*prev_lane_adjust & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
+			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
+			return -EINVAL;
+		}
+	} else {
+		*prev_lane_adjust = link_status[4];
+	}
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8 target_linkrate,
+				u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	if (*status_control == 1) {
+		if (mtk_dp->train_info.tps4) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_TRAINING_PATTERN_4;
+		} else if (mtk_dp->train_info.tps3) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_3;
+		} else {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_2;
+		}
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				val);
+
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 2;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
+					   mtk_dp->rx_cap);
+
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (!drm_dp_clock_recovery_ok(link_status,
+				      target_lane_count)) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
+		return -EINVAL;
+	}
+
+	if (drm_dp_channel_eq_ok(link_status,
+				 target_lane_count)) {
+		mtk_dp->train_info.eq_done = true;
+		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
+		return 0;
+	}
+
+	if (*prev_lane_adjust == link_status[4])
+		(*iteration_count)++;
+	else
+		*prev_lane_adjust = link_status[4];
+
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_flow(struct mtk_dp *mtk_dp, u8 target_link_rate,
+			     u8 target_lane_count)
+{
+	u8 lane_adjust[2] = {};
+	bool pass_tps1 = false;
+	bool pass_tps2_3 = false;
+	int train_retries;
+	int status_control;
+	int iteration_count;
+	int ret;
+	u8 prev_lane_adjust;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LINK_BW_SET, target_link_rate);
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count | DP_LANE_COUNT_ENHANCED_FRAME_EN);
+
+	if (mtk_dp->train_info.sink_ssc)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DOWNSPREAD_CTRL,
+				   DP_SPREAD_AMP_0_5);
+
+	train_retries = 0;
+	status_control = 0;
+	iteration_count = 1;
+	prev_lane_adjust = 0xFF;
+
+	mtk_dp_set_lanes(mtk_dp, target_lane_count / 2);
+	ret = mtk_dp_phy_configure(mtk_dp, target_link_rate, target_lane_count);
+	if (ret)
+		return -EINVAL;
+
+	dev_dbg(mtk_dp->dev,
+		"Link train target_link_rate = 0x%x, target_lane_count = 0x%x\n",
+		target_link_rate, target_lane_count);
+
+	do {
+		train_retries++;
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    ((mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) !=
+		     0x0)) {
+			return -ENODEV;
+		}
+
+		if (mtk_dp->train_state < MTK_DP_TRAIN_STATE_TRAINING)
+			return -EAGAIN;
+
+		if (!pass_tps1) {
+			ret = mtk_dp_train_tps_1(mtk_dp, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps1 = true;
+				train_retries = 0;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		} else {
+			ret = mtk_dp_train_tps_2_3(mtk_dp, target_link_rate, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps2_3 = true;
+				break;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		}
+
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_ADJUST_REQUEST_LANE0_1,
+				 lane_adjust, sizeof(lane_adjust));
+		mtk_dp_train_update_swing_pre(mtk_dp, target_lane_count,
+					      lane_adjust);
+	} while (train_retries < MTK_DP_TRAIN_RETRY_LIMIT &&
+		 iteration_count < MTK_DP_TRAIN_MAX_ITERATIONS);
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET,
+			   DP_TRAINING_PATTERN_DISABLE);
+	ret = mtk_dp_train_set_pattern(mtk_dp, 0);
+	if (ret)
+		return -EINVAL;
+
+	if (!pass_tps2_3)
+		return -ETIMEDOUT;
+
+	mtk_dp->train_info.link_rate = target_link_rate;
+	mtk_dp->train_info.lane_count = target_lane_count;
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, true);
+	if (ret)
+		return ret;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count |
+				   DP_LANE_COUNT_ENHANCED_FRAME_EN);
+	ret = mtk_dp_set_enhanced_frame_mode(mtk_dp, true);
+
+	return ret;
+}
+
+static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+{
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+	u8 val;
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	if (!mtk_dp_plug_state(mtk_dp))
+		return false;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
+	/* Wait for power on */
+	usleep_range(2000, 5000);
+
+	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+
+	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap), sizeof(buf)));
+	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &= DP_TRAINING_AUX_RD_MASK;
+
+	train_info->link_rate =
+		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp->max_linkrate]);
+	train_info->lane_count =
+		min_t(int, mtk_dp->max_lanes, drm_dp_max_lane_count(buf));
+
+	train_info->tps3 = drm_dp_tps3_supported(buf);
+	train_info->tps4 = drm_dp_tps4_supported(buf);
+
+	train_info->sink_ssc =
+		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
+
+	train_info->sink_ssc = false;
+
+	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
+	if (val & DP_MST_CAP) {
+		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
+		drm_dp_dpcd_readb(&mtk_dp->aux,
+				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, &val);
+		if (val)
+			drm_dp_dpcd_writeb(&mtk_dp->aux,
+					   DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
+					   val);
+	}
+
+	return true;
+}
+
+static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
+{
+	phy_reset(mtk_dp->phy);
+	mtk_dp_reset_swing_pre_emphasis(mtk_dp);
+}
+
+static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+	u8 lane_count;
+	u8 link_rate;
+	u8 train_limit;
+	u8 max_link_rate;
+	u8 plug_wait;
+
+	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait > 0;
+	     --plug_wait)
+		/* Avoid short pulses on the HPD isr */
+		usleep_range(1000, 5000);
+	if (plug_wait == 0) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+		return -ENODEV;
+	}
+
+	link_rate = mtk_dp->rx_cap[1];
+	lane_count = mtk_dp->rx_cap[2] & 0x1F;
+
+	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate, link_rate);
+	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes, lane_count);
+	link_rate = mtk_dp->train_info.link_rate;
+	lane_count = mtk_dp->train_info.lane_count;
+
+	switch (link_rate) {
+	case MTK_DP_LINKRATE_RBR:
+	case MTK_DP_LINKRATE_HBR:
+	case MTK_DP_LINKRATE_HBR2:
+	case MTK_DP_LINKRATE_HBR25:
+	case MTK_DP_LINKRATE_HBR3:
+		break;
+	default:
+		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
+		break;
+	};
+
+	max_link_rate = link_rate;
+	for (train_limit = 6; train_limit > 0; train_limit--) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+
+		mtk_dp_train_change_mode(mtk_dp);
+		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
+		if (ret)
+			return ret;
+
+		if (!mtk_dp->train_info.cr_done) {
+			switch (link_rate) {
+			case MTK_DP_LINKRATE_RBR:
+				lane_count = lane_count / 2;
+				link_rate = max_link_rate;
+				if (lane_count == 0) {
+					mtk_dp->train_state =
+						MTK_DP_TRAIN_STATE_DPIDLE;
+					return -EIO;
+				}
+				break;
+			case MTK_DP_LINKRATE_HBR:
+				link_rate = MTK_DP_LINKRATE_RBR;
+				break;
+			case MTK_DP_LINKRATE_HBR2:
+				link_rate = MTK_DP_LINKRATE_HBR;
+				break;
+			case MTK_DP_LINKRATE_HBR3:
+				link_rate = MTK_DP_LINKRATE_HBR2;
+				break;
+			default:
+				return -EINVAL;
+			};
+		} else if (!mtk_dp->train_info.eq_done) {
+			if (lane_count == 0)
+				return -EIO;
+
+			lane_count /= 2;
+		} else {
+			break;
+		}
+	}
+
+	if (train_limit == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+//TODO: check drm_dp_helpers for duplicated code
+
+static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	if (enable) {
+		mtk_dp_set_tx_out(mtk_dp);
+		mtk_dp_video_mute(mtk_dp, false);
+	} else {
+		mtk_dp_video_mute(mtk_dp, true);
+	}
+}
+
+static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_mn_overwrite_disable(mtk_dp);
+
+	mtk_dp_set_msa(mtk_dp);
+
+	mtk_dp_set_color_depth(mtk_dp, mtk_dp->info.depth);
+	mtk_dp_set_color_format(mtk_dp, mtk_dp->info.format);
+}
+
+static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
+{
+	switch (mtk_dp->state) {
+	case MTK_DP_STATE_INITIAL:
+		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp->state = MTK_DP_STATE_IDLE;
+		break;
+
+	case MTK_DP_STATE_IDLE:
+		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
+			mtk_dp->state = MTK_DP_STATE_PREPARE;
+		break;
+
+	case MTK_DP_STATE_PREPARE:
+		mtk_dp_video_config(mtk_dp);
+		mtk_dp_video_enable(mtk_dp, true);
+
+		mtk_dp->state = MTK_DP_STATE_NORMAL;
+		break;
+
+	case MTK_DP_STATE_NORMAL:
+		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
+			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp->state = MTK_DP_STATE_IDLE;
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
+{
+	bool training_done = false;
+	short max_retry = 50;
+	int ret = 0;
+
+	do {
+		switch (mtk_dp->train_state) {
+		case MTK_DP_TRAIN_STATE_STARTUP:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKCAP:
+			if (mtk_dp_parse_capabilities(mtk_dp)) {
+				mtk_dp->train_info.check_cap_count = 0;
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+			} else {
+				mtk_dp->train_info.check_cap_count++;
+
+				if (mtk_dp->train_info.check_cap_count >
+				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT) {
+					mtk_dp->train_info.check_cap_count = 0;
+					mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+					ret = -ETIMEDOUT;
+				}
+			}
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKEDID:
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING:
+			ret = mtk_dp_train_start(mtk_dp);
+			if (ret == 0) {
+				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
+				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
+			} else if (ret != -EAGAIN) {
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+			}
+			break;
+		case MTK_DP_TRAIN_STATE_NORMAL:
+			mtk_dp_state_handler(mtk_dp);
+			training_done = true;
+			break;
+		case MTK_DP_TRAIN_STATE_DPIDLE:
+			break;
+		default:
+			break;
+		}
+
+		if (ret) {
+			if (ret == -EAGAIN)
+				continue;
+			/*
+			 * If we get any other error number, it doesn't
+			 * make any sense to keep iterating.
+			 */
+			break;
+		}
+	} while (!training_done || --max_retry);
+
+	return ret;
+}
+
+static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_set_idle_pattern(mtk_dp, true);
+	mtk_dp_initialize_priv_data(mtk_dp);
+
+	mtk_dp_initialize_settings(mtk_dp);
+	mtk_dp_initialize_aux_settings(mtk_dp);
+	mtk_dp_initialize_digital_settings(mtk_dp);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690,
+			   BIT(RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT),
+			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK);
+	mtk_dp_initialize_hpd_detect_settings(mtk_dp);
+
+	mtk_dp_digital_sw_reset(mtk_dp);
+}
+
+static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	int event;
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+
+	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected :
+						  connector_status_disconnected;
+
+	if (event < 0)
+		return IRQ_HANDLED;
+
+	if (mtk_dp->drm_dev) {
+		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
+		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
+	}
+
+	if (mtk_dp->train_info.cable_state_change) {
+		mtk_dp->train_info.cable_state_change = false;
+
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    !mtk_dp_plug_state(mtk_dp)) {
+			mtk_dp_video_mute(mtk_dp, true);
+
+			mtk_dp_initialize_priv_data(mtk_dp);
+			mtk_dp_set_idle_pattern(mtk_dp, true);
+			if (mtk_dp->has_fec)
+				mtk_dp_fec_enable(mtk_dp, false);
+
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL,
+					   DP_PWR_STATE_MASK);
+		} else {
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL_LANE,
+					   DP_PWR_STATE_MASK);
+			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+			mtk_dp->train_info.link_rate =
+				min_t(int, mtk_dp->max_linkrate,
+				      buf[mtk_dp->max_linkrate]);
+			mtk_dp->train_info.lane_count =
+				min_t(int, mtk_dp->max_lanes,
+				      drm_dp_max_lane_count(buf));
+		}
+	}
+
+	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
+		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
+		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
+		mtk_dp_hpd_sink_event(mtk_dp);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
+{
+	bool connected;
+	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
+	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	train_info->irq_status |= hwirq_status | swirq_status;
+
+	if (!train_info->irq_status)
+		return IRQ_HANDLED;
+
+	connected = mtk_dp_plug_state(mtk_dp);
+	if (connected || !train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+	else if (!connected || train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;
+
+	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+		train_info->cable_plugged_in = true;
+	} else {
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+		train_info->cable_plugged_in = false;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	}
+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	u32 irq_status;
+
+	irq_status = mtk_dp_read(mtk_dp, MTK_DP_TOP_IRQ_STATUS);
+
+	if (!irq_status)
+		return IRQ_HANDLED;
+
+	if (irq_status & RGS_IRQ_STATUS_TRANSMITTER)
+		return mtk_dp_hpd_isr_handler(mtk_dp);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
+			   struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	mtk_dp->regs = devm_regmap_init_mmio(dev, base, &mtk_dp_regmap_config);
+	if (IS_ERR(mtk_dp->regs))
+		return PTR_ERR(mtk_dp->regs);
+
+	mtk_dp->dp_tx_clk = devm_clk_get(dev, "faxi");
+	if (IS_ERR(mtk_dp->dp_tx_clk)) {
+		dev_err(dev, "Failed to get dptx clock: %d\n", ret);
+		mtk_dp->dp_tx_clk = NULL;
+		return PTR_ERR(mtk_dp->dp_tx_clk);
+	}
+
+	ret = device_property_read_u8(dev, "max-lanes", &mtk_dp->max_lanes);
+	if (ret)
+		return ret;
+
+	ret = device_property_read_u8(dev, "max-linkrate", &mtk_dp->max_linkrate);
+
+	return ret;
+}
+
+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 enabled = mtk_dp->enabled;
+	struct edid *new_edid = NULL;
+
+//TODO: refcount enabled so that we don't have any surprises...
+
+	if (!enabled)
+		drm_bridge_chain_pre_enable(bridge);
+
+	if (mtk_dp_plug_state(mtk_dp))
+		new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc);
+
+	if (!enabled)
+		drm_bridge_chain_post_disable(bridge);
+
+	return new_edid;
+}
+
+static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+				   struct drm_dp_aux_msg *msg)
+{
+	struct mtk_dp *mtk_dp;
+	bool is_read;
+	u8 request;
+	size_t accessed_bytes = 0;
+	int ret = 0;
+
+	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
+
+	if (!mtk_dp->train_info.cable_plugged_in ||
+	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+		return -EAGAIN;
+	}
+
+	switch (msg->request) {
+	case DP_AUX_I2C_MOT:
+	case DP_AUX_I2C_WRITE:
+	case DP_AUX_NATIVE_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
+		request = msg->request & ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
+		is_read = false;
+		break;
+	case DP_AUX_I2C_READ:
+	case DP_AUX_NATIVE_READ:
+	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
+		request = msg->request;
+		is_read = true;
+		break;
+	default:
+		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
+			msg->request);
+		return -EINVAL;
+	}
+
+	if (msg->size == 0) {
+		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
+					     msg->address + accessed_bytes,
+					     msg->buffer + accessed_bytes, 0);
+	} else {
+		while (accessed_bytes < msg->size) {
+			size_t to_access =
+				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
+				      msg->size - accessed_bytes);
+
+			ret = mtk_dp_aux_do_transfer(mtk_dp,
+						     is_read, request,
+							 msg->address + accessed_bytes,
+							 msg->buffer + accessed_bytes,
+							 to_access);
+
+			if (ret) {
+				drm_info(mtk_dp->drm_dev,
+					 "Failed to do AUX transfer: %d\n", ret);
+				break;
+			}
+			accessed_bytes += to_access;
+		}
+	}
+
+	if (ret) {
+		msg->reply = DP_AUX_NATIVE_REPLY_NACK | DP_AUX_I2C_REPLY_NACK;
+		return ret;
+	}
+
+	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
+	return msg->size;
+}
+
+static void mtk_dp_poweroff(struct mtk_dp *mtk_dp)
+{
+	mutex_lock(&mtk_dp->dp_lock);
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+	mtk_dp_power_disable(mtk_dp);
+	phy_exit(mtk_dp->phy);
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+
+	mutex_unlock(&mtk_dp->dp_lock);
+}
+
+static int mtk_dp_poweron(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->dp_lock);
+
+	ret = clk_prepare_enable(mtk_dp->dp_tx_clk);
+	if (ret < 0) {
+		dev_err(mtk_dp->dev, "Fail to enable clock: %d\n", ret);
+		goto err;
+	}
+	ret = phy_init(mtk_dp->phy);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to initialize phy: %d\n", ret);
+		goto err_phy_init;
+	}
+	ret = mtk_dp_phy_configure(mtk_dp, MTK_DP_LINKRATE_RBR, 1);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to configure phy: %d\n", ret);
+		goto err_phy_config;
+	}
+
+	mtk_dp_init_port(mtk_dp);
+	ret = mtk_dp_power_enable(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+
+err_phy_config:
+	phy_exit(mtk_dp->phy);
+err_phy_init:
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+err:
+	mutex_unlock(&mtk_dp->dp_lock);
+	return ret;
+}
+
+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;
+
+	ret = mtk_dp_poweron(mtk_dp);
+	if (ret)
+		return ret;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mtk_dp->dev, "Driver does not provide a connector!");
+		return -EINVAL;
+	}
+
+	if (mtk_dp->next_bridge) {
+		ret = drm_bridge_attach(bridge->encoder, mtk_dp->next_bridge,
+					&mtk_dp->bridge, flags);
+		if (ret) {
+			drm_warn(mtk_dp->drm_dev,
+				 "Failed to attach external bridge: %d\n", ret);
+			return ret;
+		}
+	}
+
+	mtk_dp->drm_dev = bridge->dev;
+
+	return 0;
+}
+
+static void mtk_dp_bridge_detach(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->drm_dev = NULL;
+}
+
+static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp->state = MTK_DP_STATE_IDLE;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+	mtk_dp->enabled = false;
+	/* Ensure the sink is muted before powering off */
+	msleep(100);
+	mtk_dp_poweroff(mtk_dp);
+}
+
+static void mtk_dp_parse_drm_mode_timings(struct mtk_dp *mtk_dp,
+					  struct drm_display_mode *mode)
+{
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_to_videomode(mode, &timings->vm);
+	timings->frame_rate = drm_mode_vrefresh(mode);
+}
+
+static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
+					struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->conn = drm_atomic_get_new_connector_for_encoder(old_state->base.state,
+								bridge->encoder);
+	if (!mtk_dp->conn) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector is missing\n");
+		return;
+	}
+
+	/* Training */
+	if (mtk_dp_train_handler(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev, "Training failed\n");
+		return;
+	}
+
+	mtk_dp->enabled = true;
+}
+
+static enum drm_mode_status
+mtk_dp_bridge_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+	u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24;
+
+	if (rx_linkrate * mtk_dp->train_info.lane_count < mode->clock * bpp / 8)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock > 600000)
+		return MODE_CLOCK_HIGH;
+
+	if ((mode->clock * 1000) / (mode->htotal * mode->vtotal) > MTK_VDOSYS1_MAX_FRAMERATE)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *output_fmts;
+
+	*num_output_fmts = 0;
+	output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL);
+	if (!output_fmts)
+		return NULL;
+	*num_output_fmts = 1;
+	output_fmts[0] = MEDIA_BUS_FMT_FIXED;
+	return output_fmts;
+}
+
+static const u32 mt8195_input_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *input_fmts;
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+	struct drm_display_info *display_info =
+		&conn_state->connector->display_info;
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+
+	*num_input_fmts = 0;
+
+	if (((rx_linkrate * mtk_dp->train_info.lane_count) <
+	     (mode->clock * 24 / 8)) &&
+	    ((rx_linkrate * mtk_dp->train_info.lane_count) >
+	     (mode->clock * 16 / 8)) &&
+	    (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+		input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+		*num_input_fmts = 1;
+		input_fmts[0] = MEDIA_BUS_FMT_YUYV8_1X16;
+	} else {
+		input_fmts = kcalloc(ARRAY_SIZE(mt8195_input_fmts), sizeof(*input_fmts),
+				     GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+
+		*num_input_fmts = ARRAY_SIZE(mt8195_input_fmts);
+		memcpy(input_fmts, mt8195_input_fmts, sizeof(mt8195_input_fmts));
+	}
+
+	return input_fmts;
+}
+
+static int mtk_dp_bridge_atomic_check(struct drm_bridge *bridge,
+				      struct drm_bridge_state *bridge_state,
+				      struct drm_crtc_state *crtc_state,
+				      struct drm_connector_state *conn_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_crtc *crtc = conn_state->crtc;
+	unsigned int input_bus_format;
+
+	input_bus_format = bridge_state->input_bus_cfg.format;
+
+	dev_dbg(mtk_dp->dev, "input format 0x%04x, output format 0x%04x\n",
+		bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
+
+	mtk_dp->input_fmt = input_bus_format;
+	if (mtk_dp->input_fmt == MEDIA_BUS_FMT_YUYV8_1X16)
+		mtk_dp->info.format = DP_PIXELFORMAT_YUV422;
+	else
+		mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+
+	if (!crtc) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector state doesn't have a crtc\n");
+		return -EINVAL;
+	}
+
+	mtk_dp_parse_drm_mode_timings(mtk_dp, &crtc_state->adjusted_mode);
+	if (!mtk_dp_parse_capabilities(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as nothing is plugged in\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
+	.atomic_check = mtk_dp_bridge_atomic_check,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_get_output_bus_fmts = mtk_dp_bridge_atomic_get_output_bus_fmts,
+	.atomic_get_input_bus_fmts = mtk_dp_bridge_atomic_get_input_bus_fmts,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.attach = mtk_dp_bridge_attach,
+	.detach = mtk_dp_bridge_detach,
+	.atomic_enable = mtk_dp_bridge_atomic_enable,
+	.atomic_disable = mtk_dp_bridge_atomic_disable,
+	.mode_valid = mtk_dp_bridge_mode_valid,
+	.get_edid = mtk_dp_get_edid,
+};
+
+static int mtk_dp_probe(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp;
+	struct device *dev = &pdev->dev;
+	int ret;
+	int irq_num = 0;
+
+	mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
+	if (!mtk_dp)
+		return -ENOMEM;
+
+	mtk_dp->dev = dev;
+
+	irq_num = platform_get_irq(pdev, 0);
+	if (irq_num < 0)
+		return dev_err_probe(dev, irq_num, "failed to request dp irq resource\n");
+
+	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+	if (IS_ERR(mtk_dp->next_bridge)) {
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
+	}
+
+	ret = mtk_dp_dt_parse(mtk_dp, pdev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to parse dt\n");
+
+	drm_dp_aux_init(&mtk_dp->aux);
+	mtk_dp->aux.name = "aux_mtk_dp";
+	mtk_dp->aux.transfer = mtk_dp_aux_transfer;
+
+	ret = devm_request_threaded_irq(dev, irq_num, mtk_dp_hpd_event,
+					mtk_dp_hpd_event_thread,
+					IRQ_TYPE_LEVEL_HIGH, dev_name(dev),
+					mtk_dp);
+	if (ret)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
+
+	mutex_init(&mtk_dp->dp_lock);
+
+	platform_set_drvdata(pdev, mtk_dp);
+
+	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
+							PLATFORM_DEVID_AUTO,
+							&mtk_dp->regs,
+							sizeof(struct regmap *));
+	if (IS_ERR(mtk_dp->phy_dev))
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev), "Failed to create device mediatek-dp-phy\n");
+
+	mtk_dp_get_calibration_data(mtk_dp);
+
+	mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
+
+	if (IS_ERR(mtk_dp->phy)) {
+		platform_device_unregister(mtk_dp->phy_dev);
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n");
+	}
+
+	mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
+	mtk_dp->bridge.of_node = dev->of_node;
+
+	mtk_dp->bridge.ops =
+		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
+	drm_bridge_add(&mtk_dp->bridge);
+	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_remove(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp = platform_get_drvdata(pdev);
+
+	platform_device_unregister(mtk_dp->phy_dev);
+	mtk_dp_video_mute(mtk_dp, true);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_dp_suspend(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
+		/* Ensure the sink is off before shutting down power */
+		usleep_range(2000, 3000);
+	}
+
+	ret = mtk_dp_power_disable(mtk_dp);
+	if (ret)
+		return ret;
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+
+	mtk_dp_init_port(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+	ret = mtk_dp_power_enable(mtk_dp);
+
+	return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
+
+static const struct of_device_id mtk_dp_of_match[] = {
+	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{},
+};
+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 = &mtk_dp_pm_ops,
+	},
+};
+
+MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DisplayPort Driver");
+MODULE_LICENSE("GPL");
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 000000000000..848e5f697737
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
@@ -0,0 +1,570 @@
+/* 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                                             \
+	(BIT(0) | BIT(1) | BIT(5) | BIT(8) | BIT(10) | BIT(25) | BIT(31))
+#define MTK_DP_SIP_ATF_VIDEO_UNMUTE	BIT(5)
+#define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE (BIT(0) | BIT(5))
+
+#define DP_PHY_GLB_BIAS_GEN_00	  0
+#define RG_XTP_GLB_BIAS_INTR_CTRL GENMASK(20, 16)
+
+#define DP_PHY_GLB_DPAUX_TX    BIT(3)
+#define RG_CKM_PT0_CKTX_IMPSEL GENMASK(23, 20)
+
+#define DP_PHY_LANE_TX_0	  (BIT(2) | BIT(8))
+#define RG_XTP_LN0_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN0_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_1	  (BIT(2) | BIT(9))
+#define RG_XTP_LN1_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN1_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_2	  (BIT(2) | BIT(8) | BIT(9))
+#define RG_XTP_LN2_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN2_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_3	  (BIT(2) | BIT(10))
+#define RG_XTP_LN3_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN3_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define TOP_OFFSET   BIT(13)
+#define ENC0_OFFSET  GENMASK(13, 12)
+#define ENC1_OFFSET  (BIT(9) | BIT(12) | BIT(13))
+#define TRANS_OFFSET (BIT(10) | BIT(12) | BIT(13))
+#define AUX_OFFSET   (BIT(9) | BIT(10) | BIT(12) | BIT(13))
+#define SEC_OFFSET   BIT(14)
+
+#define MTK_DP_HPD_DISCONNECT BIT(1)
+#define MTK_DP_HPD_CONNECT    BIT(2)
+#define MTK_DP_HPD_INTERRUPT  BIT(3)
+
+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
+#define DA_XTP_GLB_CKDET_EN_FORCE_VAL BIT(15)
+#define DA_XTP_GLB_CKDET_EN_FORCE_EN  BIT(14)
+#define DA_CKM_INTCKTX_EN_FORCE_VAL   BIT(13)
+#define DA_CKM_INTCKTX_EN_FORCE_EN    BIT(12)
+#define DA_CKM_CKTX0_EN_FORCE_VAL     BIT(11)
+#define DA_CKM_CKTX0_EN_FORCE_EN      BIT(10)
+#define DA_CKM_XTAL_CK_FORCE_VAL      BIT(9)
+#define DA_CKM_XTAL_CK_FORCE_EN	      BIT(8)
+#define DA_CKM_BIAS_LPF_EN_FORCE_VAL  BIT(7)
+#define DA_CKM_BIAS_LPF_EN_FORCE_EN   BIT(6)
+#define DA_CKM_BIAS_EN_FORCE_VAL      BIT(5)
+#define DA_CKM_BIAS_EN_FORCE_EN	      BIT(4)
+#define DA_XTP_GLB_AVD10_ON_FORCE_VAL BIT(3)
+#define DA_XTP_GLB_AVD10_ON_FORCE     BIT(2)
+#define DA_XTP_GLB_LDO_EN_FORCE_VAL   BIT(1)
+#define DA_XTP_GLB_LDO_EN_FORCE_EN    BIT(0)
+
+#define MTK_DP_1040		      (BIT(6) | BIT(12))
+#define RG_DPAUX_RX_VALID_DEGLITCH_EN BIT(2)
+#define RG_XTP_GLB_CKDET_EN	      BIT(1)
+#define RG_DPAUX_RX_EN		      BIT(0)
+
+#define MTK_DP_ENC0_P0_3000		   (ENC0_OFFSET + 0x00)
+#define LANE_NUM_DP_ENC0_P0_MASK	   GENMASK(1, 0)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_MASK	   BIT(2)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT	   BIT(1)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_MASK	   BIT(3)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT	   GENMASK(1, 0)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_MASK  BIT(4)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT BIT(2)
+
+#define MTK_DP_ENC0_P0_3004			   (ENC0_OFFSET + 0x04)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK	   BIT(8)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_SHIFT	   BIT(3)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK  BIT(9)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT (BIT(0) | BIT(3))
+
+#define MTK_DP_ENC0_P0_3008		  (ENC0_OFFSET + 0x08)
+#define VIDEO_M_CODE_SW_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_300C		  (ENC0_OFFSET + 0x0C)
+#define VIDEO_M_CODE_SW_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3010	  (ENC0_OFFSET + 0x10)
+#define HTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3014	  (ENC0_OFFSET + 0x14)
+#define VTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3018	  (ENC0_OFFSET + 0x18)
+#define HSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_301C	  (ENC0_OFFSET + 0x1C)
+#define VSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3020	  (ENC0_OFFSET + 0x20)
+#define HWIDTH_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3024	   (ENC0_OFFSET + 0x24)
+#define VHEIGHT_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3028	(ENC0_OFFSET + 0x28)
+#define HSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define HSW_SW_DP_ENC0_P0_SHIFT 0
+#define HSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_302C	(ENC0_OFFSET + 0x2C)
+#define VSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define VSW_SW_DP_ENC0_P0_SHIFT 0
+#define VSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_3030			 (ENC0_OFFSET + 0x30)
+#define HTOTAL_SEL_DP_ENC0_P0_SHIFT		 0
+#define VTOTAL_SEL_DP_ENC0_P0_SHIFT		 BIT(0)
+#define HSTART_SEL_DP_ENC0_P0_SHIFT		 BIT(1)
+#define VSTART_SEL_DP_ENC0_P0_SHIFT		 GENMASK(1, 0)
+#define HWIDTH_SEL_DP_ENC0_P0_SHIFT		 BIT(2)
+#define VHEIGHT_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(2))
+#define HSP_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 1)
+#define HSW_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 0)
+#define VSP_SEL_DP_ENC0_P0_SHIFT		 BIT(3)
+#define VSW_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK	 (BIT(11))
+#define VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT	 (BIT(0) | BIT(1) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK (BIT(12))
+#define VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT	 GENMASK(3, 2)
+
+#define MTK_DP_ENC0_P0_3034 (ENC0_OFFSET + 0x34)
+
+#define MTK_DP_ENC0_P0_3038		  (ENC0_OFFSET + 0x38)
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK  (BIT(11))
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_SHIFT (BIT(0) | BIT(1) | BIT(3))
+
+#define MTK_DP_ENC0_P0_303C		      (ENC0_OFFSET + 0x3C)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT 0
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK     GENMASK(10, 8)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT    BIT(3)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT                                     \
+	(0 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT                                     \
+	(1 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT                                     \
+	(2 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT                                      \
+	(3 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT                                      \
+	(4 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK  GENMASK(14, 12)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT GENMASK(3, 2)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB                                     \
+	(0 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422                                \
+	(1 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420                                \
+	(2 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK	 (BIT(15))
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT GENMASK(3, 0)
+
+#define MTK_DP_ENC0_P0_3040		   (ENC0_OFFSET + 0x40)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_3044	       (ENC0_OFFSET + 0x44)
+#define VIDEO_N_CODE_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3048	       (ENC0_OFFSET + 0x48)
+#define VIDEO_N_CODE_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_304C		      (ENC0_OFFSET + 0x4C)
+#define VBID_VIDEO_MUTE_DP_ENC0_P0_MASK	      BIT(2)
+#define SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK BIT(8)
+
+#define MTK_DP_ENC0_P0_3050		      (ENC0_OFFSET + 0x50)
+#define VIDEO_N_CODE_MN_GEN_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3054		      (ENC0_OFFSET + 0x54)
+#define VIDEO_N_CODE_MN_GEN_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3064	     (ENC0_OFFSET + 0x64)
+#define HDE_NUM_LAST_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3088	      (ENC0_OFFSET + 0x88)
+#define AU_EN_DP_ENC0_P0_MASK	      BIT(6)
+#define AU_EN_DP_ENC0_P0_SHIFT	      GENMASK(2, 1)
+#define AUDIO_8CH_EN_DP_ENC0_P0_MASK  BIT(7)
+#define AUDIO_8CH_SEL_DP_ENC0_P0_MASK BIT(8)
+#define AUDIO_2CH_EN_DP_ENC0_P0_MASK  (BIT(14))
+#define AUDIO_2CH_SEL_DP_ENC0_P0_MASK (BIT(15))
+
+#define MTK_DP_ENC0_P0_308C	    (ENC0_OFFSET + 0x8C)
+#define CH_STATUS_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3090	    (ENC0_OFFSET + 0x90)
+#define CH_STATUS_1_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3094	    (ENC0_OFFSET + 0x94)
+#define CH_STATUS_2_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A0 (ENC0_OFFSET + 0xA0)
+
+#define MTK_DP_ENC0_P0_30A4	  (ENC0_OFFSET + 0xA4)
+#define AU_TS_CFG_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A8 (ENC0_OFFSET + 0xA8)
+
+#define MTK_DP_ENC0_P0_30AC (ENC0_OFFSET + 0xAC)
+
+#define MTK_DP_ENC0_P0_30B0 (ENC0_OFFSET + 0xB0)
+
+#define MTK_DP_ENC0_P0_30B4	  (ENC0_OFFSET + 0xB4)
+#define ISRC_CFG_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define ISRC_CFG_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_30B8 (ENC0_OFFSET + 0xB8)
+
+#define MTK_DP_ENC0_P0_30BC			   (ENC0_OFFSET + 0xBC)
+#define ISRC_CONT_DP_ENC0_P0_MASK		   BIT(0)
+#define ISRC_CONT_DP_ENC0_P0_SHIFT		   0
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK  GENMASK(10, 8)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT BIT(3)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_2                             \
+	(1 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_4                             \
+	(2 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_8                             \
+	(3 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2                             \
+	(5 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_4                             \
+	(6 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_8                             \
+	(7 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+
+#define MTK_DP_ENC0_P0_30D8 (ENC0_OFFSET + 0xD8)
+
+#define MTK_DP_ENC0_P0_312C	 (ENC0_OFFSET + 0x12C)
+#define ASP_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define ASP_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define ASP_HB3_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_3130 (ENC0_OFFSET + 0x130)
+
+#define MTK_DP_ENC0_P0_3138 (ENC0_OFFSET + 0x138)
+
+#define MTK_DP_ENC0_P0_3154	    (ENC0_OFFSET + 0x154)
+#define PGEN_HTOTAL_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3158		  (ENC0_OFFSET + 0x158)
+#define PGEN_HSYNC_RISING_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_315C		       (ENC0_OFFSET + 0x15C)
+#define PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3160		(ENC0_OFFSET + 0x160)
+#define PGEN_HFDE_START_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3164		       (ENC0_OFFSET + 0x164)
+#define PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3168	    (ENC0_OFFSET + 0x168)
+#define PGEN_VTOTAL_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_316C		  (ENC0_OFFSET + 0x16C)
+#define PGEN_VSYNC_RISING_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3170		       (ENC0_OFFSET + 0x170)
+#define PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3174		(ENC0_OFFSET + 0x174)
+#define PGEN_VFDE_START_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3178		       (ENC0_OFFSET + 0x178)
+#define PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_31B0    (ENC0_OFFSET + 0x1B0)
+#define PGEN_PATTERN_SEL_SHIFT BIT(2)
+#define PGEN_PATTERN_SEL_MASK  GENMASK(6, 4)
+
+#define MTK_DP_ENC0_P0_31C8		  (ENC0_OFFSET + 0x1C8)
+#define VSC_EXT_VESA_HB0_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31CC		  (ENC0_OFFSET + 0x1CC)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_VESA_HB3_DP_ENC0_P0_MASK  GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D0		 (ENC0_OFFSET + 0x1D0)
+#define VSC_EXT_CEA_HB0_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31D4		 (ENC0_OFFSET + 0x1D4)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D8		  (ENC0_OFFSET + 0x1D8)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_MASK	  GENMASK(13, 8)
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_SHIFT  BIT(3)
+
+#define MTK_DP_ENC0_P0_31DC	  (ENC0_OFFSET + 0x1DC)
+#define HDR0_CFG_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define HDR0_CFG_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_31E8 (ENC0_OFFSET + 0x1E8)
+
+#define MTK_DP_ENC0_P0_31EC		  (ENC0_OFFSET + 0x1EC)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK  BIT(4)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT BIT(2)
+#define ISRC1_HB3_DP_ENC0_P0_MASK	  GENMASK(15, 8)
+#define ISRC1_HB3_DP_ENC0_P0_SHIFT	  BIT(3)
+
+#define MTK_DP_ENC1_P0_3200 (ENC1_OFFSET + 0x00)
+
+#define MTK_DP_ENC1_P0_3280		(ENC1_OFFSET + 0x80)
+#define SDP_PACKET_TYPE_DP_ENC1_P0_MASK GENMASK(4, 0)
+#define SDP_PACKET_W_DP_ENC1_P0		BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_MASK	BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_SHIFT	(BIT(0) | BIT(2))
+
+#define MTK_DP_ENC1_P0_328C (ENC1_OFFSET + 0x8C)
+
+#define MTK_DP_ENC1_P0_3290 (ENC1_OFFSET + 0x90)
+
+#define MTK_DP_ENC1_P0_32A0 (ENC1_OFFSET + 0xA0)
+
+#define MTK_DP_ENC1_P0_32A4 (ENC1_OFFSET + 0xA4)
+
+#define MTK_DP_ENC1_P0_3300		     (ENC1_OFFSET + 0x100)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC1_P0_3304			  (ENC1_OFFSET + 0x104)
+#define AU_PRTY_REGEN_DP_ENC1_P0_MASK		  BIT(8)
+#define AU_CH_STS_REGEN_DP_ENC1_P0_MASK		  BIT(9)
+#define AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK (BIT(12))
+
+#define MTK_DP_ENC1_P0_3324		  (ENC1_OFFSET + 0x124)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT BIT(3)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX                                       \
+	(0 << AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT)
+
+#define MTK_DP_ENC1_P0_3364			     (ENC1_OFFSET + 0x164)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT 0
+#define FIFO_READ_START_POINT_DP_ENC1_P0_MASK	     GENMASK(15, 12)
+#define FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT	     GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_3368			       (ENC1_OFFSET + 0x168)
+#define VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT 0
+#define VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT	       BIT(2)
+#define SDP_DP13_EN_DP_ENC1_P0_SHIFT		       BIT(3)
+#define BS2BS_MODE_DP_ENC1_P0_MASK		       GENMASK(13, 12)
+#define BS2BS_MODE_DP_ENC1_P0_SHIFT		       GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_33F4 (ENC1_OFFSET + 0x1F4)
+
+#define MTK_DP_TRANS_P0_3400	      (TRANS_OFFSET + 0)
+#define PATTERN1_EN_DP_TRANS_P0_MASK  BIT(12)
+#define PATTERN1_EN_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+#define PATTERN2_EN_DP_TRANS_P0_MASK  BIT(13)
+#define PATTERN3_EN_DP_TRANS_P0_MASK  BIT(14)
+#define PATTERN4_EN_DP_TRANS_P0_MASK  BIT(15)
+
+#define MTK_DP_TRANS_P0_3404	   (TRANS_OFFSET + 0x4)
+#define DP_SCR_EN_DP_TRANS_P0_MASK BIT(0)
+
+#define MTK_DP_TRANS_P0_340C			       (TRANS_OFFSET + 0xC)
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK (BIT(13))
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT                        \
+	(BIT(0) | BIT(2) | BIT(3))
+
+#define MTK_DP_TRANS_P0_3410		    (TRANS_OFFSET + 0x10)
+#define HPD_DEB_THD_DP_TRANS_P0_MASK	    GENMASK(3, 0)
+#define HPD_DEB_THD_DP_TRANS_P0_SHIFT	    0
+#define HPD_INT_THD_DP_TRANS_P0_MASK	    GENMASK(7, 4)
+#define HPD_INT_THD_DP_TRANS_P0_SHIFT	    BIT(2)
+#define HPD_INT_THD_DP_TRANS_P0_LOWER_500US (2 << HPD_INT_THD_DP_TRANS_P0_SHIFT)
+#define HPD_INT_THD_DP_TRANS_P0_UPPER_1100US                                   \
+	(2 << (HPD_INT_THD_DP_TRANS_P0_SHIFT + 2))
+#define HPD_DISC_THD_DP_TRANS_P0_MASK  GENMASK(11, 8)
+#define HPD_DISC_THD_DP_TRANS_P0_SHIFT BIT(3)
+#define HPD_CONN_THD_DP_TRANS_P0_MASK  GENMASK(15, 12)
+#define HPD_CONN_THD_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_3414	(TRANS_OFFSET + 0x14)
+#define HPD_DB_DP_TRANS_P0_MASK BIT(2)
+
+#define MTK_DP_TRANS_P0_3418	      (TRANS_OFFSET + 0x18)
+#define IRQ_CLR_DP_TRANS_P0_MASK      GENMASK(3, 0)
+#define IRQ_MASK_DP_TRANS_P0_MASK     GENMASK(7, 4)
+#define IRQ_MASK_DP_TRANS_P0_SHIFT    BIT(2)
+#define IRQ_MASK_DP_TRANS_P0_DISC_IRQ (BIT(1) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_CONN_IRQ (BIT(2) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_INT_IRQ  (BIT(3) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_STATUS_DP_TRANS_P0_MASK   GENMASK(15, 12)
+#define IRQ_STATUS_DP_TRANS_P0_SHIFT  GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_342C	      (TRANS_OFFSET + 0x2C)
+#define XTAL_FREQ_DP_TRANS_P0_DEFAULT (BIT(0) | BIT(3) | BIT(5) | BIT(6))
+#define XTAL_FREQ_DP_TRANS_P0_MASK    GENMASK(7, 0)
+
+#define MTK_DP_TRANS_P0_3430			   (TRANS_OFFSET + 0x30)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_MASK	   GENMASK(1, 0)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT BIT(1)
+
+#define MTK_DP_TRANS_P0_34A4	   (TRANS_OFFSET + 0xA4)
+#define LANE_NUM_DP_TRANS_P0_MASK  GENMASK(3, 2)
+#define LANE_NUM_DP_TRANS_P0_SHIFT BIT(1)
+
+#define MTK_DP_TRANS_P0_3540		    (TRANS_OFFSET + 0x140)
+#define FEC_EN_DP_TRANS_P0_MASK		    BIT(0)
+#define FEC_EN_DP_TRANS_P0_SHIFT	    0
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK  BIT(3)
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_TRANS_P0_3580			 (TRANS_OFFSET + 0x180)
+#define POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK BIT(8)
+#define POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK BIT(9)
+#define POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK (BIT(10))
+#define POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK (BIT(11))
+
+#define MTK_DP_TRANS_P0_35C4	     (TRANS_OFFSET + 0x1C4)
+#define SW_IRQ_MASK_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35C8	    (TRANS_OFFSET + 0x1C8)
+#define SW_IRQ_CLR_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define SW_IRQ_STATUS_DP_TRANS_P0_MASK	GENMASK(15, 0)
+#define SW_IRQ_STATUS_DP_TRANS_P0_SHIFT 0
+
+#define MTK_DP_TRANS_P0_35D0		     (TRANS_OFFSET + 0x1D0)
+#define SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35F0 (TRANS_OFFSET + 0x1F0)
+
+#define MTK_DP_AUX_P0_360C	       (AUX_OFFSET + 0xC)
+#define AUX_TIMEOUT_THR_AUX_TX_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_AUX_P0_3614		  (AUX_OFFSET + 0x14)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK  GENMASK(6, 0)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3618			 (AUX_OFFSET + 0x18)
+#define AUX_RX_FIFO_FULL_AUX_TX_P0_MASK		 BIT(9)
+#define AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3620		      (AUX_OFFSET + 0x20)
+#define AUX_RD_MODE_AUX_TX_P0_MASK	      BIT(9)
+#define AUX_RX_FIFO_READ_PULSE_TX_P0_MASK     BIT(8)
+#define AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT	      BIT(3)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK  GENMASK(7, 0)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3624		    (AUX_OFFSET + 0x24)
+#define AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3628		 (AUX_OFFSET + 0x28)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_MASK	 GENMASK(9, 0)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT 0
+#define AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE                                     \
+	(BIT(0) << AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT)
+
+#define MTK_DP_AUX_P0_362C		  (AUX_OFFSET + 0x2C)
+#define AUX_NO_LENGTH_AUX_TX_P0_MASK	  BIT(0)
+#define AUX_NO_LENGTH_AUX_TX_P0_SHIFT	  0
+#define AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK BIT(1)
+#define AUX_RESERVED_RW_0_AUX_TX_P0_MASK  GENMASK(15, 2)
+
+#define MTK_DP_AUX_P0_3630		     (AUX_OFFSET + 0x30)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_MASK  BIT(3)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_AUX_P0_3634			(AUX_OFFSET + 0x34)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK	GENMASK(15, 8)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3640			      (AUX_OFFSET + 0x40)
+#define AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK	      BIT(6)
+#define AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT  GENMASK(2, 1)
+#define AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT (BIT(0) | BIT(2))
+#define AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT BIT(2)
+#define AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT	      GENMASK(1, 0)
+#define AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(1)
+#define AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT	      0
+
+#define MTK_DP_AUX_P0_3644		   (AUX_OFFSET + 0x44)
+#define MCU_REQUEST_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3648		       (AUX_OFFSET + 0x48)
+#define MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_AUX_P0_364C		       (AUX_OFFSET + 0x4C)
+#define MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3650		      (AUX_OFFSET + 0x50)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_MASK	      GENMASK(15, 12)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT      GENMASK(3, 2)
+#define PHY_FIFO_RST_AUX_TX_P0_MASK	      BIT(9)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK  BIT(8)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3658	    (AUX_OFFSET + 0x58)
+#define AUX_TX_OV_EN_AUX_TX_P0_MASK BIT(0)
+
+#define MTK_DP_AUX_P0_3690		       (AUX_OFFSET + 0x90)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK  BIT(8)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3704				      (AUX_OFFSET + 0x104)
+#define AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK BIT(1)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK		      BIT(2)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT		      BIT(1)
+
+#define MTK_DP_AUX_P0_3708 (AUX_OFFSET + 0x108)
+
+#define MTK_DP_AUX_P0_37C8	    (AUX_OFFSET + 0x1C8)
+#define MTK_ATOP_EN_AUX_TX_P0_MASK  BIT(0)
+#define MTK_ATOP_EN_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_TOP_PWR_STATE	       (TOP_OFFSET + 0x0)
+#define DP_PWR_STATE_MASK	       GENMASK(1, 0)
+#define DP_PWR_STATE_BANDGAP	       BIT(0)
+#define DP_PWR_STATE_BANDGAP_TPLL      BIT(1)
+#define DP_PWR_STATE_BANDGAP_TPLL_LANE GENMASK(1, 0)
+
+#define MTK_DP_TOP_SWING_EMP	(TOP_OFFSET + 0x4)
+#define DP_TX0_VOLT_SWING_MASK	GENMASK(1, 0)
+#define DP_TX0_VOLT_SWING_SHIFT 0
+#define DP_TX0_PRE_EMPH_MASK	GENMASK(3, 2)
+#define DP_TX0_PRE_EMPH_SHIFT	BIT(1)
+#define DP_TX1_VOLT_SWING_MASK	GENMASK(9, 8)
+#define DP_TX1_VOLT_SWING_SHIFT BIT(3)
+#define DP_TX1_PRE_EMPH_MASK	GENMASK(11, 10)
+#define DP_TX2_VOLT_SWING_MASK	GENMASK(17, 16)
+#define DP_TX2_PRE_EMPH_MASK	GENMASK(19, 18)
+#define DP_TX3_VOLT_SWING_MASK	GENMASK(25, 24)
+#define DP_TX3_PRE_EMPH_MASK	GENMASK(27, 26)
+
+#define MTK_DP_TOP_RESET_AND_PROBE (TOP_OFFSET + 0x20)
+#define SW_RST_B_SHIFT		   0
+#define SW_RST_B_PHYD		   (BIT(4) << SW_RST_B_SHIFT)
+
+#define MTK_DP_TOP_IRQ_STATUS	   (TOP_OFFSET + 0x28)
+#define RGS_IRQ_STATUS_SHIFT	   0
+#define RGS_IRQ_STATUS_TRANSMITTER (BIT(1) << RGS_IRQ_STATUS_SHIFT)
+
+#define MTK_DP_TOP_IRQ_MASK  (TOP_OFFSET + 0x2C)
+#define IRQ_MASK_AUX_TOP_IRQ BIT(2)
+
+#define MTK_DP_TOP_MEM_PD (TOP_OFFSET + 0x38)
+#define MEM_ISO_EN_SHIFT  0
+#define FUSE_SEL_SHIFT	  BIT(1)
+
+#endif /*_MTK_DP_REG_H_*/
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index e25ac61aac08..4e378eb34071 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -906,6 +906,9 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+	&mtk_dp_driver,
+#endif
 	&mtk_drm_platform_driver,
 	&mtk_dsi_driver,
 	&mtk_ethdr_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 8d3ff32b5364..04de9436ea85 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -59,6 +59,9 @@ extern struct platform_driver mtk_disp_ovl_adaptor_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+extern struct platform_driver mtk_dp_driver;
+#endif
 extern struct platform_driver mtk_dsi_driver;
 extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.

It supports the mt8195, the embedded DisplayPort units. It offers
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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/Kconfig       |    8 +
 drivers/gpu/drm/mediatek/Makefile      |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2570 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  570 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |    3 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |    3 +
 6 files changed, 3156 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..a37b6ec9f01e 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -21,6 +21,14 @@ config DRM_MEDIATEK
 	  This driver provides kernel mode setting and
 	  buffer management to userspace.
 
+config DRM_MEDIATEK_DP
+	tristate "DRM DPTX Support for Mediatek SoCs"
+	depends on DRM_MEDIATEK
+	select PHY_MTK_DP
+	select DRM_DP_HELPER
+	help
+	  DRM/KMS Display Port driver for Mediatek SoCs.
+
 config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 3abd27d7c91d..d4d193f60271 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_DRM_MEDIATEK_DP) += 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 000000000000..8eb17ae82bfd
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +-2,2567 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/dp/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/hdmi-codec.h>
+#include <video/videomode.h>
+
+#include "mtk_dp_reg.h"
+
+#define MTK_VDOSYS1_MAX_FRAMERATE 60
+#define MTK_DP_4P1T 4
+#define MTK_DP_HDE 2
+#define MTK_DP_PIX_PER_ADDR 2
+#define MTK_DP_AUX_WAIT_REPLY_COUNT 20
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT 3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT 8
+#define MTK_DP_TRAIN_MAX_ITERATIONS 5
+
+#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_NORMAL,
+	MTK_DP_TRAIN_STATE_DPIDLE,
+};
+
+struct mtk_dp_timings {
+	struct videomode vm;
+
+	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;
+
+	u8  irq_status;
+	int check_cap_count;
+};
+
+/* 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,
+};
+
+//TODO: redundant with DP_MSA_MISC_*_BPC ?
+/* Same values as used for DP Spec MISC0 bits 5,6,7 */
+enum mtk_dp_color_depth {
+	MTK_DP_COLOR_DEPTH_6BIT = 0,
+	MTK_DP_COLOR_DEPTH_8BIT = 1,
+	MTK_DP_COLOR_DEPTH_10BIT = 2,
+	MTK_DP_COLOR_DEPTH_12BIT = 3,
+	MTK_DP_COLOR_DEPTH_16BIT = 4,
+	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
+};
+
+struct mtk_dp_info {
+	enum mtk_dp_color_depth depth;
+	enum dp_pixelformat format;
+	struct mtk_dp_timings timings;
+};
+
+struct dp_cal_data {
+	unsigned int glb_bias_trim;
+	unsigned int clktx_impse;
+
+	unsigned int *ln_tx_impsel_pmos;
+	unsigned int *ln_tx_impsel_nmos;
+};
+
+struct mtk_dp {
+	struct device *dev;
+	struct platform_device *phy_dev;
+	struct phy *phy;
+	struct dp_cal_data cal_data;
+	u8 max_lanes;
+	u8 max_linkrate;
+
+	struct drm_device *drm_dev;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_dp_aux aux;
+
+	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
+
+	struct mtk_dp_info info;
+	enum mtk_dp_state state;
+
+	struct mtk_dp_train_info train_info;
+	enum mtk_dp_train_state train_state;
+	unsigned int input_fmt;
+
+	struct regmap *regs;
+	struct clk *dp_tx_clk;
+
+	bool enabled;
+
+	bool has_fec;
+	/* Protects the mtk_dp struct */
+	struct mutex dp_lock;
+
+	struct drm_connector *conn;
+};
+
+static struct regmap_config mtk_dp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = SEC_OFFSET + 0x90,
+	.name = "mtk-dp-registers",
+};
+
+static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
+{
+	return container_of(b, struct mtk_dp, bridge);
+}
+
+static u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
+{
+	u32 read_val;
+	int ret;
+
+	ret = regmap_read(mtk_dp->regs, offset, &read_val);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to read register 0x%x: %d\n",
+			offset, ret);
+		return 0;
+	}
+
+	return read_val;
+}
+
+static int mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
+{
+	int ret;
+
+	ret = regmap_write(mtk_dp->regs, offset, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to write register 0x%x with value 0x%x: %d\n",
+			offset, val, ret);
+	return ret;
+}
+
+static int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset, u32 val,
+			      u32 mask)
+{
+	int ret;
+
+	ret = regmap_update_bits(mtk_dp->regs, offset, mask, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to update register 0x%x with value 0x%x, mask 0x%x: %d\n",
+			offset, val, mask, ret);
+	return ret;
+}
+
+static int mtk_dp_bulk_16bit_write(struct mtk_dp *mtk_dp, u32 offset, u8 *buf,
+				   size_t length)
+{
+	int i;
+	int ret = 0;
+	int num_regs = (length + 1) / 2;
+
+	/* 2 bytes per register */
+	for (i = 0; i < num_regs; i++) {
+		u32 val = buf[i * 2] |
+			  (i * 2 + 1 < length ? buf[i * 2 + 1] << 8 : 0);
+
+		ret = mtk_dp_write(mtk_dp, offset + i * 4, val);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static unsigned long mtk_dp_sip_atf_call(unsigned int cmd, unsigned int para)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32, cmd, para, 0, 0, 0, 0, 0,
+		      &res);
+
+	pr_debug("[DPTX]%s cmd 0x%x, p1 0x%x, ret 0x%lx-0x%lx", __func__, cmd,
+		 para, res.a0, res.a1);
+	return res.a1;
+}
+
+static int mtk_dp_msa_bypass_disable(struct mtk_dp *mtk_dp)
+{
+	const u16 bits_to_set =
+		BIT(HTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HWIDTH_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VHEIGHT_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSP_SEL_DP_ENC0_P0_SHIFT) | BIT(HSW_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSP_SEL_DP_ENC0_P0_SHIFT) | BIT(VSW_SEL_DP_ENC0_P0_SHIFT);
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3030, bits_to_set,
+			   bits_to_set);
+}
+
+static int mtk_dp_set_msa(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3010, mode.htotal,
+				 HTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3018,
+				 timings->vm.hsync_len + timings->vm.hback_porch,
+			   HSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028,
+				 timings->vm.hsync_len << HSW_SW_DP_ENC0_P0_SHIFT,
+			   HSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028, 0,
+				 HSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3020, timings->vm.hactive,
+				 HWIDTH_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3014, mode.vtotal,
+				 VTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_301C,
+				 timings->vm.vsync_len + timings->vm.vback_porch,
+			   VSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C,
+				 timings->vm.vsync_len << VSW_SW_DP_ENC0_P0_SHIFT,
+			   VSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C, 0,
+				 VSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3024, timings->vm.vactive,
+				 VHEIGHT_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3064, timings->vm.hactive,
+				 HDE_NUM_LAST_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3154, mode.htotal,
+				 PGEN_HTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3158,
+				 timings->vm.hfront_porch,
+			   PGEN_HSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_315C, timings->vm.hsync_len,
+				 PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
+				 timings->vm.hback_porch + timings->vm.hsync_len,
+			   PGEN_HFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3164, timings->vm.hactive,
+				 PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3168, mode.vtotal,
+				 PGEN_VTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_316C,
+				 timings->vm.vfront_porch,
+			   PGEN_VSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3170, timings->vm.vsync_len,
+				 PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
+				 timings->vm.vback_porch + timings->vm.vsync_len,
+			   PGEN_VFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3178, timings->vm.vactive,
+				 PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
+				   enum dp_pixelformat color_format)
+{
+	u32 val;
+	int ret;
+
+	mtk_dp->info.format = color_format;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_format << DP_TEST_COLOR_FORMAT_SHIFT,
+				 DP_TEST_COLOR_FORMAT_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_format) {
+	case DP_PIXELFORMAT_YUV422:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422;
+		break;
+	case DP_PIXELFORMAT_YUV420:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420;
+		break;
+	case DP_PIXELFORMAT_RGB:
+	case DP_PIXELFORMAT_YUV444:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
+		break;
+	case DP_PIXELFORMAT_Y_ONLY:
+	case DP_PIXELFORMAT_RAW:
+	case DP_PIXELFORMAT_RESERVED:
+	default:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
+			 color_format);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_color_depth(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_color_depth color_depth)
+{
+	int ret;
+	u32 val;
+
+	mtk_dp->info.depth = color_depth;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_depth << DP_TEST_BIT_DEPTH_SHIFT,
+				 DP_TEST_BIT_DEPTH_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_depth) {
+	case MTK_DP_COLOR_DEPTH_6BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_8BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_10BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_12BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_16BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_UNKNOWN:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color depth %d\n",
+			 color_depth);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_mn_overwrite_disable(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				  VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_sram_read_start(struct mtk_dp *mtk_dp, u32 val)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				  val << SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT,
+				  SRAM_START_READ_THRD_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_setup_encoder(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				 BIT(VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT),
+				 VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+				 0x20 << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 0x20 << SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3300,
+				 2 << VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT,
+			    VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 4 << FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT,
+			    FIFO_READ_START_POINT_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368,
+			   1 << VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT |
+			   1 << VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT |
+			   BIT(SDP_DP13_EN_DP_ENC1_P0_SHIFT) |
+			   1 << BS2BS_MODE_DP_ENC1_P0_SHIFT);
+
+	return ret;
+}
+
+static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3038, 0,
+				 VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31B0,
+				 4 << PGEN_PATTERN_SEL_SHIFT, PGEN_PATTERN_SEL_MASK);
+
+	return ret;
+}
+
+static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
+{
+	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
+		  HPD_DB_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT));
+	/* Wait for the irq to be cleared */
+	usleep_range(MTK_DP_AUX_WRITE_READ_WAIT_TIME_US,
+		     MTK_DP_AUX_WRITE_READ_WAIT_TIME_US * 2);
+}
+
+static int mtk_dp_aux_set_cmd(struct mtk_dp *mtk_dp, u8 cmd, u32 addr)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3644, cmd,
+				 MCU_REQUEST_COMMAND_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3648, addr,
+				 MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_364C, addr >> 16,
+				 MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_aux_cmd_complete(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+				  BIT(MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT),
+				  MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK |
+				  PHY_FIFO_RST_AUX_TX_P0_MASK |
+				  MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+}
+
+static int mtk_dp_aux_request_ready(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3630,
+				  BIT(AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT),
+				  AUX_TX_REQUEST_READY_AUX_TX_P0_MASK);
+}
+
+static void mtk_dp_aux_fill_write_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				       size_t length)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_AUX_P0_3708, buf, length);
+}
+
+static int mtk_dp_aux_read_rx_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				   size_t length, int read_delay)
+{
+	int ret;
+	int read_pos;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620, 0,
+				 AUX_RD_MODE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+
+	for (read_pos = 0; read_pos < length; read_pos++) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620,
+					 BIT(AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT),
+					 AUX_RX_FIFO_READ_PULSE_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Hardware needs time to update the data */
+		usleep_range(read_delay, read_delay * 2);
+		buf[read_pos] =
+			(u8)(mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3620) &
+			     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK >>
+				     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_set_length(struct mtk_dp *mtk_dp, size_t length)
+{
+	int ret;
+
+	if (length > 0) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+					 (length - 1)
+					 << MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT,
+					 MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C,
+					 BIT(AUX_NO_LENGTH_AUX_TX_P0_SHIFT),
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_wait_for_completion(struct mtk_dp *mtk_dp, bool is_read)
+{
+	int wait_reply = MTK_DP_AUX_WAIT_REPLY_COUNT;
+
+	while (--wait_reply) {
+		u32 aux_irq_status;
+
+		if (is_read) {
+			u32 fifo_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3618);
+
+			if (fifo_status &
+			    (AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK |
+			     AUX_RX_FIFO_FULL_AUX_TX_P0_MASK)) {
+				return 0;
+			}
+		}
+
+		aux_irq_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3640);
+		if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK)
+			return 0;
+
+		if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK)
+			return -ETIMEDOUT;
+
+		/* Give the hardware a chance to reach completion before retrying */
+		usleep_range(100, 500);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
+				  u32 addr, u8 *buf, size_t length)
+{
+	int ret;
+	u32 reply_cmd;
+
+	if (is_read && (length > DP_AUX_MAX_PAYLOAD_BYTES ||
+			(cmd == DP_AUX_NATIVE_READ && !length)))
+		return -EINVAL;
+
+	if (!is_read) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 BIT(AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT),
+					 AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	mtk_dp_aux_set_cmd(mtk_dp, cmd, addr);
+	mtk_dp_aux_set_length(mtk_dp, length);
+
+	if (!is_read) {
+		if (length)
+			mtk_dp_aux_fill_write_fifo(mtk_dp, buf, length);
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_request_ready(mtk_dp);
+
+	ret = mtk_dp_aux_wait_for_completion(mtk_dp, is_read);
+
+	reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
+		    AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
+
+	if (ret || reply_cmd) {
+		u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
+				 AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
+		if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) {
+			drm_err(mtk_dp->drm_dev,
+				"AUX Rx Aux hang, need SW reset\n");
+			return -EIO;
+		}
+
+		mtk_dp_aux_cmd_complete(mtk_dp);
+		mtk_dp_aux_irq_clear(mtk_dp);
+
+		return -ETIMEDOUT;
+	}
+
+	if (!length) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+
+	} else if (is_read) {
+		int read_delay;
+
+		if (cmd == (DP_AUX_I2C_READ | DP_AUX_I2C_MOT) ||
+		    cmd == DP_AUX_I2C_READ)
+			read_delay = 500;
+		else
+			read_delay = 100;
+
+		mtk_dp_aux_read_rx_fifo(mtk_dp, buf, length, read_delay);
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	return 0;
+}
+
+static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
+					  int swing_val, int preemphasis)
+{
+	int ret;
+
+	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
+
+	if (lane_num < 0 || lane_num > 3)
+		return false;
+
+	dev_dbg(mtk_dp->dev,
+		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
+		swing_val, preemphasis);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 swing_val << (DP_TX0_VOLT_SWING_SHIFT + lane_shift),
+				 DP_TX0_VOLT_SWING_MASK << lane_shift);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT + lane_shift),
+				 DP_TX0_PRE_EMPH_MASK << lane_shift);
+
+	return !ret;
+}
+
+static int mtk_dp_reset_swing_pre_emphasis(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP, 0,
+				  DP_TX0_VOLT_SWING_MASK | DP_TX1_VOLT_SWING_MASK |
+				  DP_TX2_VOLT_SWING_MASK |
+				  DP_TX3_VOLT_SWING_MASK |
+				  DP_TX0_PRE_EMPH_MASK | DP_TX1_PRE_EMPH_MASK |
+				  DP_TX2_PRE_EMPH_MASK | DP_TX3_PRE_EMPH_MASK);
+}
+
+static int mtk_dp_fec_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				  enable ? BIT(FEC_EN_DP_TRANS_P0_SHIFT) : 0,
+				  FEC_EN_DP_TRANS_P0_MASK);
+}
+
+static u32 mtk_dp_swirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u32 irq_status = mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_35D0) &
+			 SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, irq_status,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, 0,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+	}
+
+	return irq_status;
+}
+
+static u32 mtk_dp_hwirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u8 irq_status = (mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3418) &
+			 IRQ_STATUS_DP_TRANS_P0_MASK) >>
+			IRQ_STATUS_DP_TRANS_P0_SHIFT;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, irq_status,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, 0,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+	}
+
+	return irq_status;
+}
+
+static int mtk_dp_hwirq_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = enable ? 0 : IRQ_MASK_DP_TRANS_P0_DISC_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_CONN_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_INT_IRQ;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, val,
+			   IRQ_MASK_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_342C,
+				 XTAL_FREQ_DP_TRANS_P0_DEFAULT,
+			   XTAL_FREQ_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				 BIT(FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT),
+			   FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+				 BIT(AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT),
+			   AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_IRQ_MASK, IRQ_MASK_AUX_TOP_IRQ,
+				 IRQ_MASK_AUX_TOP_IRQ);
+
+	return ret;
+}
+
+static void mtk_dp_initialize_hpd_detect_settings(struct mtk_dp *mtk_dp)
+{
+	/* Debounce threshold */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   8 << HPD_DEB_THD_DP_TRANS_P0_SHIFT,
+			   HPD_DEB_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
+			    HPD_INT_THD_DP_TRANS_P0_UPPER_1100US)
+				   << HPD_INT_THD_DP_TRANS_P0_SHIFT,
+			   HPD_INT_THD_DP_TRANS_P0_MASK);
+
+	/* Connect threshold 1.5ms + 5 x 0.1ms = 2ms
+	 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (5 << HPD_DISC_THD_DP_TRANS_P0_SHIFT) |
+				   (5 << HPD_CONN_THD_DP_TRANS_P0_SHIFT),
+			   HPD_DISC_THD_DP_TRANS_P0_MASK |
+				   HPD_CONN_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	/* modify timeout threshold = 1595 [12 : 8] */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_360C, 0x1595,
+				 AUX_TIMEOUT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3658, 0,
+				 AUX_TX_OV_EN_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 25 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3634,
+				 25 << AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT,
+			   AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 13 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3614,
+				 13 << AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT,
+			   AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_37C8,
+				 BIT(MTK_ATOP_EN_AUX_TX_P0_SHIFT),
+			   MTK_ATOP_EN_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 VBID_VIDEO_MUTE_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	mtk_dp_set_color_format(mtk_dp, DP_PIXELFORMAT_RGB);
+	mtk_dp_set_color_depth(mtk_dp, MTK_DP_COLOR_DEPTH_8BIT);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3368,
+				 1 << BS2BS_MODE_DP_ENC1_P0_SHIFT,
+			   BS2BS_MODE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* dp tx encoder reset all sw */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
+				 BIT(DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT),
+			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				 DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_digital_sw_reset(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C,
+				 BIT(DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT),
+			   DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C, 0,
+				 DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_lanes(struct mtk_dp *mtk_dp, int lanes)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35F0,
+				 lanes == 0 ? 0 : BIT(3), BIT(3) | BIT(2));
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, lanes,
+				 LANE_NUM_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4,
+				 lanes << LANE_NUM_DP_TRANS_P0_SHIFT,
+			   LANE_NUM_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int link_rate_to_mb_per_s(struct mtk_dp *mtk_dp,
+				 enum mtk_dp_linkrate linkrate)
+{
+	switch (linkrate) {
+	case MTK_DP_LINKRATE_RBR:
+		return 1620;
+	case MTK_DP_LINKRATE_HBR:
+		return 2700;
+	case MTK_DP_LINKRATE_HBR2:
+		return 5400;
+	case MTK_DP_LINKRATE_HBR3:
+		return 8100;
+	default:
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, unknown linkrate %d\n",
+			linkrate);
+		return -EINVAL;
+	}
+}
+
+static u32 check_cal_data_valid(struct mtk_dp *mtk_dp, u32 min, u32 max, u32 val, u32 default_val)
+{
+	if (val < min || val > max)
+		dev_warn(mtk_dp->dev, "Invalid calibration data: %d (< %d || > %d), returning default %d\n",
+			 val, min, max, default_val);
+		return default_val;
+
+	return val;
+}
+
+static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
+{
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+	struct device *dev = mtk_dp->dev;
+	struct nvmem_cell *cell;
+	u32 *buf;
+	size_t len;
+
+	cell = nvmem_cell_get(dev, "dp_calibration_data");
+	if (IS_ERR(cell)) {
+		dev_err(dev,
+			"Error: Failed to get nvmem cell dp_calibration_data\n");
+		return PTR_ERR(cell);
+	}
+
+	buf = (u32 *)nvmem_cell_read(cell, &len);
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) {
+		dev_err(dev,
+			"Error: Failed to read nvmem_cell_read fail len %ld\n",
+			(len / sizeof(u32)));
+		return PTR_ERR(buf);
+	}
+
+	cal_data->ln_tx_impsel_nmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_nmos)
+		return -ENOMEM;
+
+	cal_data->ln_tx_impsel_pmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_pmos)
+		return -ENOMEM;
+
+	cal_data->glb_bias_trim =
+		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+	cal_data->clktx_impse =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int mtk_dp_set_cal_data(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_DPAUX_TX,
+				 cal_data->clktx_impse << 20, RG_CKM_PT0_CKTX_IMPSEL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_BIAS_GEN_00,
+				 cal_data->glb_bias_trim << 16,
+			   RG_XTP_GLB_BIAS_INTR_CTRL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_pmos[0] << 12,
+			   RG_XTP_LN0_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_nmos[0] << 16,
+			   RG_XTP_LN0_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_pmos[1] << 12,
+			   RG_XTP_LN1_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_nmos[1] << 16,
+			   RG_XTP_LN1_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_pmos[2] << 12,
+			   RG_XTP_LN2_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_nmos[2] << 16,
+			   RG_XTP_LN2_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_pmos[3] << 12,
+			   RG_XTP_LN3_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_nmos[3] << 16,
+			   RG_XTP_LN3_TX_IMPSEL_NMOS);
+
+	return ret;
+}
+
+static int mtk_dp_phy_configure(struct mtk_dp *mtk_dp,
+				enum mtk_dp_linkrate link_rate, int lane_count)
+{
+	int ret;
+	union phy_configure_opts phy_opts = {
+		.dp = {
+			.link_rate = link_rate_to_mb_per_s(mtk_dp, link_rate),
+			.set_rate = 1,
+			.lanes = lane_count,
+			.set_lanes = 1,
+			.ssc = mtk_dp->train_info.sink_ssc,
+		}
+		};
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP,
+				 DP_PWR_STATE_MASK);
+	if (ret)
+		return ret;
+
+	ret = phy_configure(mtk_dp->phy, &phy_opts);
+
+	if (ret)
+		return ret;
+
+	mtk_dp_set_cal_data(mtk_dp);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_idle_pattern(struct mtk_dp *mtk_dp, bool enable)
+{
+	const u32 val = POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK;
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3580, enable ? val : 0, val);
+}
+
+static int mtk_dp_train_set_pattern(struct mtk_dp *mtk_dp, int pattern)
+{
+	int ret;
+
+	if (pattern < 0 || pattern > 4) {
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, no such pattern %d\n", pattern);
+		return -EINVAL;
+	}
+
+	if (pattern == 1) { /* TPS1 */
+		ret = mtk_dp_set_idle_pattern(mtk_dp, false);
+		if (ret)
+			return ret;
+	}
+
+	return mtk_dp_update_bits(mtk_dp,
+			   MTK_DP_TRANS_P0_3400,
+			   pattern ? BIT(pattern - 1) << PATTERN1_EN_DP_TRANS_P0_SHIFT : 0,
+			   PATTERN1_EN_DP_TRANS_P0_MASK | PATTERN2_EN_DP_TRANS_P0_MASK |
+			   PATTERN3_EN_DP_TRANS_P0_MASK |
+			   PATTERN4_EN_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_set_enhanced_frame_mode(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
+			   enable ? BIT(ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT) : 0,
+			   ENHANCED_FRAME_EN_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3404,
+			   enable ? DP_SCR_EN_DP_TRANS_P0_MASK : 0,
+			   DP_SCR_EN_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
+
+	if (enable)
+		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
+			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+}
+
+static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, 0,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	/* Wait for power enable */
+	usleep_range(10, 200);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, SW_RST_B_PHYD,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL,
+			   DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
+			   DA_CKM_CKTX0_EN_FORCE_EN | DA_CKM_BIAS_LPF_EN_FORCE_VAL |
+		     DA_CKM_BIAS_EN_FORCE_VAL |
+		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
+		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
+
+	if (ret)
+		return ret;
+
+	/* Disable RX */
+	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
+			   0x550 | BIT(FUSE_SEL_SHIFT) | BIT(MEM_ISO_EN_SHIFT));
+
+	return ret;
+}
+
+static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
+{
+	mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR2;
+	mtk_dp->train_info.lane_count = mtk_dp->max_lanes;
+	mtk_dp->train_info.irq_status = 0;
+	mtk_dp->train_info.cable_plugged_in = false;
+	mtk_dp->train_info.cable_state_change = false;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	mtk_dp->state = MTK_DP_STATE_INITIAL;
+
+	mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+	mtk_dp->info.depth = MTK_DP_COLOR_DEPTH_8BIT;
+	memset(&mtk_dp->info.timings, 0, sizeof(struct mtk_dp_timings));
+	mtk_dp->info.timings.frame_rate = 60;
+
+	mtk_dp->has_fec = false;
+}
+
+static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
+{
+	u32 sram_read_start = MTK_DP_TBC_BUF_READ_START_ADDR;
+
+	if (mtk_dp->train_info.lane_count > 0) {
+		sram_read_start = min_t(u32,
+					MTK_DP_TBC_BUF_READ_START_ADDR,
+					mtk_dp->info.timings.vm.hactive /
+					mtk_dp->train_info.lane_count /
+					MTK_DP_4P1T / MTK_DP_HDE / MTK_DP_PIX_PER_ADDR);
+		mtk_dp_set_sram_read_start(mtk_dp, sram_read_start);
+	}
+
+	mtk_dp_setup_encoder(mtk_dp);
+}
+
+static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
+{
+	u8 target_frame_rate = 60;
+	u32 target_pixel_clk;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.frame_rate > 0) {
+		target_frame_rate = mtk_dp->info.timings.frame_rate;
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	} else if (mtk_dp->info.timings.pix_rate_khz > 0) {
+		target_pixel_clk = mtk_dp->info.timings.pix_rate_khz * 1000;
+	} else {
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	}
+
+	mtk_dp->info.timings.pix_rate_khz = target_pixel_clk / 1000;
+}
+
+static void mtk_dp_set_tx_out(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_msa_bypass_disable(mtk_dp);
+	mtk_dp_calculate_pixrate(mtk_dp);
+	mtk_dp_pg_disable(mtk_dp);
+	mtk_dp_setup_tu(mtk_dp);
+}
+
+static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
+{
+	ssize_t ret;
+	u8 sink_count;
+	bool locked;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+	u32 sink_count_reg = DP_SINK_COUNT_ESI;
+	u32 link_status_reg = DP_LANE0_1_STATUS;
+
+	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg, &sink_count);
+	if (ret < 0) {
+		drm_err(mtk_dp->drm_dev, "Read sink count failed: %ld\n", ret);
+		return ret;
+	}
+
+	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg, link_status,
+			       sizeof(link_status));
+	if (!ret) {
+		drm_err(mtk_dp->drm_dev, "Read link status failed: %ld\n",
+			ret);
+		return ret;
+	}
+
+	locked = drm_dp_channel_eq_ok(link_status,
+				      mtk_dp->train_info.lane_count);
+	if (!locked && mtk_dp->train_state > MTK_DP_TRAIN_STATE_TRAINING_PRE)
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+
+	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR,
+				   DP_REMOTE_CONTROL_COMMAND_PENDING);
+
+	if (DP_GET_SINK_COUNT(sink_count) &&
+	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
+		mtk_dp->train_info.check_cap_count = 0;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+		msleep(20);
+	}
+
+	return 0;
+}
+
+static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
+					  u8 dpcd_adjust_req[2])
+{
+	int lane;
+
+	for (lane = 0; lane < lanes; ++lane) {
+		u8 val;
+		u8 swing;
+		u8 preemphasis;
+		int index = lane / 2;
+		int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
+
+		swing = (dpcd_adjust_req[index] >> shift) &
+			DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
+		preemphasis = ((dpcd_adjust_req[index] >> shift) &
+			       DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
+			      DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
+		val = swing << DP_TRAIN_VOLTAGE_SWING_SHIFT |
+		      preemphasis << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+		if (swing == DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
+			val |= DP_TRAIN_MAX_SWING_REACHED;
+		if (preemphasis == 3)
+			val |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+		mtk_dp_set_swing_pre_emphasis(mtk_dp, lane, swing, preemphasis);
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_LANE0_SET + lane,
+				   val);
+	}
+}
+
+static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
+				    u8 link_status[DP_LINK_STATUS_SIZE])
+{
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
+			 DP_LINK_STATUS_SIZE);
+}
+
+static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
+			      u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, false);
+	if (ret)
+		return ret;
+
+	if (*status_control == 0) {
+		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
+		if (ret)
+			return ret;
+
+		val = DP_LINK_SCRAMBLING_DISABLE |
+			DP_TRAINING_PATTERN_1;
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_1);
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 1;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
+					       mtk_dp->rx_cap);
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (drm_dp_clock_recovery_ok(link_status,
+				     target_lane_count)) {
+		mtk_dp->train_info.cr_done = true;
+		*iteration_count = 1;
+		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
+		return 0;
+	} else if (*prev_lane_adjust == link_status[4]) {
+		(*iteration_count)++;
+		if (*prev_lane_adjust & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
+			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
+			return -EINVAL;
+		}
+	} else {
+		*prev_lane_adjust = link_status[4];
+	}
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8 target_linkrate,
+				u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	if (*status_control == 1) {
+		if (mtk_dp->train_info.tps4) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_TRAINING_PATTERN_4;
+		} else if (mtk_dp->train_info.tps3) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_3;
+		} else {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_2;
+		}
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				val);
+
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 2;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
+					   mtk_dp->rx_cap);
+
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (!drm_dp_clock_recovery_ok(link_status,
+				      target_lane_count)) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
+		return -EINVAL;
+	}
+
+	if (drm_dp_channel_eq_ok(link_status,
+				 target_lane_count)) {
+		mtk_dp->train_info.eq_done = true;
+		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
+		return 0;
+	}
+
+	if (*prev_lane_adjust == link_status[4])
+		(*iteration_count)++;
+	else
+		*prev_lane_adjust = link_status[4];
+
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_flow(struct mtk_dp *mtk_dp, u8 target_link_rate,
+			     u8 target_lane_count)
+{
+	u8 lane_adjust[2] = {};
+	bool pass_tps1 = false;
+	bool pass_tps2_3 = false;
+	int train_retries;
+	int status_control;
+	int iteration_count;
+	int ret;
+	u8 prev_lane_adjust;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LINK_BW_SET, target_link_rate);
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count | DP_LANE_COUNT_ENHANCED_FRAME_EN);
+
+	if (mtk_dp->train_info.sink_ssc)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DOWNSPREAD_CTRL,
+				   DP_SPREAD_AMP_0_5);
+
+	train_retries = 0;
+	status_control = 0;
+	iteration_count = 1;
+	prev_lane_adjust = 0xFF;
+
+	mtk_dp_set_lanes(mtk_dp, target_lane_count / 2);
+	ret = mtk_dp_phy_configure(mtk_dp, target_link_rate, target_lane_count);
+	if (ret)
+		return -EINVAL;
+
+	dev_dbg(mtk_dp->dev,
+		"Link train target_link_rate = 0x%x, target_lane_count = 0x%x\n",
+		target_link_rate, target_lane_count);
+
+	do {
+		train_retries++;
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    ((mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) !=
+		     0x0)) {
+			return -ENODEV;
+		}
+
+		if (mtk_dp->train_state < MTK_DP_TRAIN_STATE_TRAINING)
+			return -EAGAIN;
+
+		if (!pass_tps1) {
+			ret = mtk_dp_train_tps_1(mtk_dp, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps1 = true;
+				train_retries = 0;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		} else {
+			ret = mtk_dp_train_tps_2_3(mtk_dp, target_link_rate, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps2_3 = true;
+				break;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		}
+
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_ADJUST_REQUEST_LANE0_1,
+				 lane_adjust, sizeof(lane_adjust));
+		mtk_dp_train_update_swing_pre(mtk_dp, target_lane_count,
+					      lane_adjust);
+	} while (train_retries < MTK_DP_TRAIN_RETRY_LIMIT &&
+		 iteration_count < MTK_DP_TRAIN_MAX_ITERATIONS);
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET,
+			   DP_TRAINING_PATTERN_DISABLE);
+	ret = mtk_dp_train_set_pattern(mtk_dp, 0);
+	if (ret)
+		return -EINVAL;
+
+	if (!pass_tps2_3)
+		return -ETIMEDOUT;
+
+	mtk_dp->train_info.link_rate = target_link_rate;
+	mtk_dp->train_info.lane_count = target_lane_count;
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, true);
+	if (ret)
+		return ret;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count |
+				   DP_LANE_COUNT_ENHANCED_FRAME_EN);
+	ret = mtk_dp_set_enhanced_frame_mode(mtk_dp, true);
+
+	return ret;
+}
+
+static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+{
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+	u8 val;
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	if (!mtk_dp_plug_state(mtk_dp))
+		return false;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
+	/* Wait for power on */
+	usleep_range(2000, 5000);
+
+	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+
+	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap), sizeof(buf)));
+	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &= DP_TRAINING_AUX_RD_MASK;
+
+	train_info->link_rate =
+		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp->max_linkrate]);
+	train_info->lane_count =
+		min_t(int, mtk_dp->max_lanes, drm_dp_max_lane_count(buf));
+
+	train_info->tps3 = drm_dp_tps3_supported(buf);
+	train_info->tps4 = drm_dp_tps4_supported(buf);
+
+	train_info->sink_ssc =
+		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
+
+	train_info->sink_ssc = false;
+
+	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
+	if (val & DP_MST_CAP) {
+		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
+		drm_dp_dpcd_readb(&mtk_dp->aux,
+				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, &val);
+		if (val)
+			drm_dp_dpcd_writeb(&mtk_dp->aux,
+					   DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
+					   val);
+	}
+
+	return true;
+}
+
+static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
+{
+	phy_reset(mtk_dp->phy);
+	mtk_dp_reset_swing_pre_emphasis(mtk_dp);
+}
+
+static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+	u8 lane_count;
+	u8 link_rate;
+	u8 train_limit;
+	u8 max_link_rate;
+	u8 plug_wait;
+
+	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait > 0;
+	     --plug_wait)
+		/* Avoid short pulses on the HPD isr */
+		usleep_range(1000, 5000);
+	if (plug_wait == 0) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+		return -ENODEV;
+	}
+
+	link_rate = mtk_dp->rx_cap[1];
+	lane_count = mtk_dp->rx_cap[2] & 0x1F;
+
+	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate, link_rate);
+	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes, lane_count);
+	link_rate = mtk_dp->train_info.link_rate;
+	lane_count = mtk_dp->train_info.lane_count;
+
+	switch (link_rate) {
+	case MTK_DP_LINKRATE_RBR:
+	case MTK_DP_LINKRATE_HBR:
+	case MTK_DP_LINKRATE_HBR2:
+	case MTK_DP_LINKRATE_HBR25:
+	case MTK_DP_LINKRATE_HBR3:
+		break;
+	default:
+		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
+		break;
+	};
+
+	max_link_rate = link_rate;
+	for (train_limit = 6; train_limit > 0; train_limit--) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+
+		mtk_dp_train_change_mode(mtk_dp);
+		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
+		if (ret)
+			return ret;
+
+		if (!mtk_dp->train_info.cr_done) {
+			switch (link_rate) {
+			case MTK_DP_LINKRATE_RBR:
+				lane_count = lane_count / 2;
+				link_rate = max_link_rate;
+				if (lane_count == 0) {
+					mtk_dp->train_state =
+						MTK_DP_TRAIN_STATE_DPIDLE;
+					return -EIO;
+				}
+				break;
+			case MTK_DP_LINKRATE_HBR:
+				link_rate = MTK_DP_LINKRATE_RBR;
+				break;
+			case MTK_DP_LINKRATE_HBR2:
+				link_rate = MTK_DP_LINKRATE_HBR;
+				break;
+			case MTK_DP_LINKRATE_HBR3:
+				link_rate = MTK_DP_LINKRATE_HBR2;
+				break;
+			default:
+				return -EINVAL;
+			};
+		} else if (!mtk_dp->train_info.eq_done) {
+			if (lane_count == 0)
+				return -EIO;
+
+			lane_count /= 2;
+		} else {
+			break;
+		}
+	}
+
+	if (train_limit == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+//TODO: check drm_dp_helpers for duplicated code
+
+static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	if (enable) {
+		mtk_dp_set_tx_out(mtk_dp);
+		mtk_dp_video_mute(mtk_dp, false);
+	} else {
+		mtk_dp_video_mute(mtk_dp, true);
+	}
+}
+
+static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_mn_overwrite_disable(mtk_dp);
+
+	mtk_dp_set_msa(mtk_dp);
+
+	mtk_dp_set_color_depth(mtk_dp, mtk_dp->info.depth);
+	mtk_dp_set_color_format(mtk_dp, mtk_dp->info.format);
+}
+
+static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
+{
+	switch (mtk_dp->state) {
+	case MTK_DP_STATE_INITIAL:
+		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp->state = MTK_DP_STATE_IDLE;
+		break;
+
+	case MTK_DP_STATE_IDLE:
+		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
+			mtk_dp->state = MTK_DP_STATE_PREPARE;
+		break;
+
+	case MTK_DP_STATE_PREPARE:
+		mtk_dp_video_config(mtk_dp);
+		mtk_dp_video_enable(mtk_dp, true);
+
+		mtk_dp->state = MTK_DP_STATE_NORMAL;
+		break;
+
+	case MTK_DP_STATE_NORMAL:
+		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
+			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp->state = MTK_DP_STATE_IDLE;
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
+{
+	bool training_done = false;
+	short max_retry = 50;
+	int ret = 0;
+
+	do {
+		switch (mtk_dp->train_state) {
+		case MTK_DP_TRAIN_STATE_STARTUP:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKCAP:
+			if (mtk_dp_parse_capabilities(mtk_dp)) {
+				mtk_dp->train_info.check_cap_count = 0;
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+			} else {
+				mtk_dp->train_info.check_cap_count++;
+
+				if (mtk_dp->train_info.check_cap_count >
+				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT) {
+					mtk_dp->train_info.check_cap_count = 0;
+					mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+					ret = -ETIMEDOUT;
+				}
+			}
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKEDID:
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING:
+			ret = mtk_dp_train_start(mtk_dp);
+			if (ret == 0) {
+				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
+				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
+			} else if (ret != -EAGAIN) {
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+			}
+			break;
+		case MTK_DP_TRAIN_STATE_NORMAL:
+			mtk_dp_state_handler(mtk_dp);
+			training_done = true;
+			break;
+		case MTK_DP_TRAIN_STATE_DPIDLE:
+			break;
+		default:
+			break;
+		}
+
+		if (ret) {
+			if (ret == -EAGAIN)
+				continue;
+			/*
+			 * If we get any other error number, it doesn't
+			 * make any sense to keep iterating.
+			 */
+			break;
+		}
+	} while (!training_done || --max_retry);
+
+	return ret;
+}
+
+static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_set_idle_pattern(mtk_dp, true);
+	mtk_dp_initialize_priv_data(mtk_dp);
+
+	mtk_dp_initialize_settings(mtk_dp);
+	mtk_dp_initialize_aux_settings(mtk_dp);
+	mtk_dp_initialize_digital_settings(mtk_dp);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690,
+			   BIT(RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT),
+			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK);
+	mtk_dp_initialize_hpd_detect_settings(mtk_dp);
+
+	mtk_dp_digital_sw_reset(mtk_dp);
+}
+
+static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	int event;
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+
+	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected :
+						  connector_status_disconnected;
+
+	if (event < 0)
+		return IRQ_HANDLED;
+
+	if (mtk_dp->drm_dev) {
+		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
+		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
+	}
+
+	if (mtk_dp->train_info.cable_state_change) {
+		mtk_dp->train_info.cable_state_change = false;
+
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    !mtk_dp_plug_state(mtk_dp)) {
+			mtk_dp_video_mute(mtk_dp, true);
+
+			mtk_dp_initialize_priv_data(mtk_dp);
+			mtk_dp_set_idle_pattern(mtk_dp, true);
+			if (mtk_dp->has_fec)
+				mtk_dp_fec_enable(mtk_dp, false);
+
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL,
+					   DP_PWR_STATE_MASK);
+		} else {
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL_LANE,
+					   DP_PWR_STATE_MASK);
+			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+			mtk_dp->train_info.link_rate =
+				min_t(int, mtk_dp->max_linkrate,
+				      buf[mtk_dp->max_linkrate]);
+			mtk_dp->train_info.lane_count =
+				min_t(int, mtk_dp->max_lanes,
+				      drm_dp_max_lane_count(buf));
+		}
+	}
+
+	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
+		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
+		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
+		mtk_dp_hpd_sink_event(mtk_dp);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
+{
+	bool connected;
+	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
+	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	train_info->irq_status |= hwirq_status | swirq_status;
+
+	if (!train_info->irq_status)
+		return IRQ_HANDLED;
+
+	connected = mtk_dp_plug_state(mtk_dp);
+	if (connected || !train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+	else if (!connected || train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;
+
+	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+		train_info->cable_plugged_in = true;
+	} else {
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+		train_info->cable_plugged_in = false;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	}
+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	u32 irq_status;
+
+	irq_status = mtk_dp_read(mtk_dp, MTK_DP_TOP_IRQ_STATUS);
+
+	if (!irq_status)
+		return IRQ_HANDLED;
+
+	if (irq_status & RGS_IRQ_STATUS_TRANSMITTER)
+		return mtk_dp_hpd_isr_handler(mtk_dp);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
+			   struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	mtk_dp->regs = devm_regmap_init_mmio(dev, base, &mtk_dp_regmap_config);
+	if (IS_ERR(mtk_dp->regs))
+		return PTR_ERR(mtk_dp->regs);
+
+	mtk_dp->dp_tx_clk = devm_clk_get(dev, "faxi");
+	if (IS_ERR(mtk_dp->dp_tx_clk)) {
+		dev_err(dev, "Failed to get dptx clock: %d\n", ret);
+		mtk_dp->dp_tx_clk = NULL;
+		return PTR_ERR(mtk_dp->dp_tx_clk);
+	}
+
+	ret = device_property_read_u8(dev, "max-lanes", &mtk_dp->max_lanes);
+	if (ret)
+		return ret;
+
+	ret = device_property_read_u8(dev, "max-linkrate", &mtk_dp->max_linkrate);
+
+	return ret;
+}
+
+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 enabled = mtk_dp->enabled;
+	struct edid *new_edid = NULL;
+
+//TODO: refcount enabled so that we don't have any surprises...
+
+	if (!enabled)
+		drm_bridge_chain_pre_enable(bridge);
+
+	if (mtk_dp_plug_state(mtk_dp))
+		new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc);
+
+	if (!enabled)
+		drm_bridge_chain_post_disable(bridge);
+
+	return new_edid;
+}
+
+static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+				   struct drm_dp_aux_msg *msg)
+{
+	struct mtk_dp *mtk_dp;
+	bool is_read;
+	u8 request;
+	size_t accessed_bytes = 0;
+	int ret = 0;
+
+	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
+
+	if (!mtk_dp->train_info.cable_plugged_in ||
+	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+		return -EAGAIN;
+	}
+
+	switch (msg->request) {
+	case DP_AUX_I2C_MOT:
+	case DP_AUX_I2C_WRITE:
+	case DP_AUX_NATIVE_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
+		request = msg->request & ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
+		is_read = false;
+		break;
+	case DP_AUX_I2C_READ:
+	case DP_AUX_NATIVE_READ:
+	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
+		request = msg->request;
+		is_read = true;
+		break;
+	default:
+		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
+			msg->request);
+		return -EINVAL;
+	}
+
+	if (msg->size == 0) {
+		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
+					     msg->address + accessed_bytes,
+					     msg->buffer + accessed_bytes, 0);
+	} else {
+		while (accessed_bytes < msg->size) {
+			size_t to_access =
+				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
+				      msg->size - accessed_bytes);
+
+			ret = mtk_dp_aux_do_transfer(mtk_dp,
+						     is_read, request,
+							 msg->address + accessed_bytes,
+							 msg->buffer + accessed_bytes,
+							 to_access);
+
+			if (ret) {
+				drm_info(mtk_dp->drm_dev,
+					 "Failed to do AUX transfer: %d\n", ret);
+				break;
+			}
+			accessed_bytes += to_access;
+		}
+	}
+
+	if (ret) {
+		msg->reply = DP_AUX_NATIVE_REPLY_NACK | DP_AUX_I2C_REPLY_NACK;
+		return ret;
+	}
+
+	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
+	return msg->size;
+}
+
+static void mtk_dp_poweroff(struct mtk_dp *mtk_dp)
+{
+	mutex_lock(&mtk_dp->dp_lock);
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+	mtk_dp_power_disable(mtk_dp);
+	phy_exit(mtk_dp->phy);
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+
+	mutex_unlock(&mtk_dp->dp_lock);
+}
+
+static int mtk_dp_poweron(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->dp_lock);
+
+	ret = clk_prepare_enable(mtk_dp->dp_tx_clk);
+	if (ret < 0) {
+		dev_err(mtk_dp->dev, "Fail to enable clock: %d\n", ret);
+		goto err;
+	}
+	ret = phy_init(mtk_dp->phy);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to initialize phy: %d\n", ret);
+		goto err_phy_init;
+	}
+	ret = mtk_dp_phy_configure(mtk_dp, MTK_DP_LINKRATE_RBR, 1);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to configure phy: %d\n", ret);
+		goto err_phy_config;
+	}
+
+	mtk_dp_init_port(mtk_dp);
+	ret = mtk_dp_power_enable(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+
+err_phy_config:
+	phy_exit(mtk_dp->phy);
+err_phy_init:
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+err:
+	mutex_unlock(&mtk_dp->dp_lock);
+	return ret;
+}
+
+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;
+
+	ret = mtk_dp_poweron(mtk_dp);
+	if (ret)
+		return ret;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mtk_dp->dev, "Driver does not provide a connector!");
+		return -EINVAL;
+	}
+
+	if (mtk_dp->next_bridge) {
+		ret = drm_bridge_attach(bridge->encoder, mtk_dp->next_bridge,
+					&mtk_dp->bridge, flags);
+		if (ret) {
+			drm_warn(mtk_dp->drm_dev,
+				 "Failed to attach external bridge: %d\n", ret);
+			return ret;
+		}
+	}
+
+	mtk_dp->drm_dev = bridge->dev;
+
+	return 0;
+}
+
+static void mtk_dp_bridge_detach(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->drm_dev = NULL;
+}
+
+static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp->state = MTK_DP_STATE_IDLE;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+	mtk_dp->enabled = false;
+	/* Ensure the sink is muted before powering off */
+	msleep(100);
+	mtk_dp_poweroff(mtk_dp);
+}
+
+static void mtk_dp_parse_drm_mode_timings(struct mtk_dp *mtk_dp,
+					  struct drm_display_mode *mode)
+{
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_to_videomode(mode, &timings->vm);
+	timings->frame_rate = drm_mode_vrefresh(mode);
+}
+
+static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
+					struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->conn = drm_atomic_get_new_connector_for_encoder(old_state->base.state,
+								bridge->encoder);
+	if (!mtk_dp->conn) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector is missing\n");
+		return;
+	}
+
+	/* Training */
+	if (mtk_dp_train_handler(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev, "Training failed\n");
+		return;
+	}
+
+	mtk_dp->enabled = true;
+}
+
+static enum drm_mode_status
+mtk_dp_bridge_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+	u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24;
+
+	if (rx_linkrate * mtk_dp->train_info.lane_count < mode->clock * bpp / 8)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock > 600000)
+		return MODE_CLOCK_HIGH;
+
+	if ((mode->clock * 1000) / (mode->htotal * mode->vtotal) > MTK_VDOSYS1_MAX_FRAMERATE)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *output_fmts;
+
+	*num_output_fmts = 0;
+	output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL);
+	if (!output_fmts)
+		return NULL;
+	*num_output_fmts = 1;
+	output_fmts[0] = MEDIA_BUS_FMT_FIXED;
+	return output_fmts;
+}
+
+static const u32 mt8195_input_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *input_fmts;
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+	struct drm_display_info *display_info =
+		&conn_state->connector->display_info;
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+
+	*num_input_fmts = 0;
+
+	if (((rx_linkrate * mtk_dp->train_info.lane_count) <
+	     (mode->clock * 24 / 8)) &&
+	    ((rx_linkrate * mtk_dp->train_info.lane_count) >
+	     (mode->clock * 16 / 8)) &&
+	    (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+		input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+		*num_input_fmts = 1;
+		input_fmts[0] = MEDIA_BUS_FMT_YUYV8_1X16;
+	} else {
+		input_fmts = kcalloc(ARRAY_SIZE(mt8195_input_fmts), sizeof(*input_fmts),
+				     GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+
+		*num_input_fmts = ARRAY_SIZE(mt8195_input_fmts);
+		memcpy(input_fmts, mt8195_input_fmts, sizeof(mt8195_input_fmts));
+	}
+
+	return input_fmts;
+}
+
+static int mtk_dp_bridge_atomic_check(struct drm_bridge *bridge,
+				      struct drm_bridge_state *bridge_state,
+				      struct drm_crtc_state *crtc_state,
+				      struct drm_connector_state *conn_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_crtc *crtc = conn_state->crtc;
+	unsigned int input_bus_format;
+
+	input_bus_format = bridge_state->input_bus_cfg.format;
+
+	dev_dbg(mtk_dp->dev, "input format 0x%04x, output format 0x%04x\n",
+		bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
+
+	mtk_dp->input_fmt = input_bus_format;
+	if (mtk_dp->input_fmt == MEDIA_BUS_FMT_YUYV8_1X16)
+		mtk_dp->info.format = DP_PIXELFORMAT_YUV422;
+	else
+		mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+
+	if (!crtc) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector state doesn't have a crtc\n");
+		return -EINVAL;
+	}
+
+	mtk_dp_parse_drm_mode_timings(mtk_dp, &crtc_state->adjusted_mode);
+	if (!mtk_dp_parse_capabilities(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as nothing is plugged in\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
+	.atomic_check = mtk_dp_bridge_atomic_check,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_get_output_bus_fmts = mtk_dp_bridge_atomic_get_output_bus_fmts,
+	.atomic_get_input_bus_fmts = mtk_dp_bridge_atomic_get_input_bus_fmts,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.attach = mtk_dp_bridge_attach,
+	.detach = mtk_dp_bridge_detach,
+	.atomic_enable = mtk_dp_bridge_atomic_enable,
+	.atomic_disable = mtk_dp_bridge_atomic_disable,
+	.mode_valid = mtk_dp_bridge_mode_valid,
+	.get_edid = mtk_dp_get_edid,
+};
+
+static int mtk_dp_probe(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp;
+	struct device *dev = &pdev->dev;
+	int ret;
+	int irq_num = 0;
+
+	mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
+	if (!mtk_dp)
+		return -ENOMEM;
+
+	mtk_dp->dev = dev;
+
+	irq_num = platform_get_irq(pdev, 0);
+	if (irq_num < 0)
+		return dev_err_probe(dev, irq_num, "failed to request dp irq resource\n");
+
+	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+	if (IS_ERR(mtk_dp->next_bridge)) {
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
+	}
+
+	ret = mtk_dp_dt_parse(mtk_dp, pdev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to parse dt\n");
+
+	drm_dp_aux_init(&mtk_dp->aux);
+	mtk_dp->aux.name = "aux_mtk_dp";
+	mtk_dp->aux.transfer = mtk_dp_aux_transfer;
+
+	ret = devm_request_threaded_irq(dev, irq_num, mtk_dp_hpd_event,
+					mtk_dp_hpd_event_thread,
+					IRQ_TYPE_LEVEL_HIGH, dev_name(dev),
+					mtk_dp);
+	if (ret)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
+
+	mutex_init(&mtk_dp->dp_lock);
+
+	platform_set_drvdata(pdev, mtk_dp);
+
+	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
+							PLATFORM_DEVID_AUTO,
+							&mtk_dp->regs,
+							sizeof(struct regmap *));
+	if (IS_ERR(mtk_dp->phy_dev))
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev), "Failed to create device mediatek-dp-phy\n");
+
+	mtk_dp_get_calibration_data(mtk_dp);
+
+	mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
+
+	if (IS_ERR(mtk_dp->phy)) {
+		platform_device_unregister(mtk_dp->phy_dev);
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n");
+	}
+
+	mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
+	mtk_dp->bridge.of_node = dev->of_node;
+
+	mtk_dp->bridge.ops =
+		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
+	drm_bridge_add(&mtk_dp->bridge);
+	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_remove(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp = platform_get_drvdata(pdev);
+
+	platform_device_unregister(mtk_dp->phy_dev);
+	mtk_dp_video_mute(mtk_dp, true);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_dp_suspend(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
+		/* Ensure the sink is off before shutting down power */
+		usleep_range(2000, 3000);
+	}
+
+	ret = mtk_dp_power_disable(mtk_dp);
+	if (ret)
+		return ret;
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+
+	mtk_dp_init_port(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+	ret = mtk_dp_power_enable(mtk_dp);
+
+	return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
+
+static const struct of_device_id mtk_dp_of_match[] = {
+	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{},
+};
+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 = &mtk_dp_pm_ops,
+	},
+};
+
+MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DisplayPort Driver");
+MODULE_LICENSE("GPL");
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 000000000000..848e5f697737
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
@@ -0,0 +1,570 @@
+/* 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                                             \
+	(BIT(0) | BIT(1) | BIT(5) | BIT(8) | BIT(10) | BIT(25) | BIT(31))
+#define MTK_DP_SIP_ATF_VIDEO_UNMUTE	BIT(5)
+#define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE (BIT(0) | BIT(5))
+
+#define DP_PHY_GLB_BIAS_GEN_00	  0
+#define RG_XTP_GLB_BIAS_INTR_CTRL GENMASK(20, 16)
+
+#define DP_PHY_GLB_DPAUX_TX    BIT(3)
+#define RG_CKM_PT0_CKTX_IMPSEL GENMASK(23, 20)
+
+#define DP_PHY_LANE_TX_0	  (BIT(2) | BIT(8))
+#define RG_XTP_LN0_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN0_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_1	  (BIT(2) | BIT(9))
+#define RG_XTP_LN1_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN1_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_2	  (BIT(2) | BIT(8) | BIT(9))
+#define RG_XTP_LN2_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN2_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_3	  (BIT(2) | BIT(10))
+#define RG_XTP_LN3_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN3_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define TOP_OFFSET   BIT(13)
+#define ENC0_OFFSET  GENMASK(13, 12)
+#define ENC1_OFFSET  (BIT(9) | BIT(12) | BIT(13))
+#define TRANS_OFFSET (BIT(10) | BIT(12) | BIT(13))
+#define AUX_OFFSET   (BIT(9) | BIT(10) | BIT(12) | BIT(13))
+#define SEC_OFFSET   BIT(14)
+
+#define MTK_DP_HPD_DISCONNECT BIT(1)
+#define MTK_DP_HPD_CONNECT    BIT(2)
+#define MTK_DP_HPD_INTERRUPT  BIT(3)
+
+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
+#define DA_XTP_GLB_CKDET_EN_FORCE_VAL BIT(15)
+#define DA_XTP_GLB_CKDET_EN_FORCE_EN  BIT(14)
+#define DA_CKM_INTCKTX_EN_FORCE_VAL   BIT(13)
+#define DA_CKM_INTCKTX_EN_FORCE_EN    BIT(12)
+#define DA_CKM_CKTX0_EN_FORCE_VAL     BIT(11)
+#define DA_CKM_CKTX0_EN_FORCE_EN      BIT(10)
+#define DA_CKM_XTAL_CK_FORCE_VAL      BIT(9)
+#define DA_CKM_XTAL_CK_FORCE_EN	      BIT(8)
+#define DA_CKM_BIAS_LPF_EN_FORCE_VAL  BIT(7)
+#define DA_CKM_BIAS_LPF_EN_FORCE_EN   BIT(6)
+#define DA_CKM_BIAS_EN_FORCE_VAL      BIT(5)
+#define DA_CKM_BIAS_EN_FORCE_EN	      BIT(4)
+#define DA_XTP_GLB_AVD10_ON_FORCE_VAL BIT(3)
+#define DA_XTP_GLB_AVD10_ON_FORCE     BIT(2)
+#define DA_XTP_GLB_LDO_EN_FORCE_VAL   BIT(1)
+#define DA_XTP_GLB_LDO_EN_FORCE_EN    BIT(0)
+
+#define MTK_DP_1040		      (BIT(6) | BIT(12))
+#define RG_DPAUX_RX_VALID_DEGLITCH_EN BIT(2)
+#define RG_XTP_GLB_CKDET_EN	      BIT(1)
+#define RG_DPAUX_RX_EN		      BIT(0)
+
+#define MTK_DP_ENC0_P0_3000		   (ENC0_OFFSET + 0x00)
+#define LANE_NUM_DP_ENC0_P0_MASK	   GENMASK(1, 0)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_MASK	   BIT(2)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT	   BIT(1)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_MASK	   BIT(3)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT	   GENMASK(1, 0)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_MASK  BIT(4)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT BIT(2)
+
+#define MTK_DP_ENC0_P0_3004			   (ENC0_OFFSET + 0x04)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK	   BIT(8)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_SHIFT	   BIT(3)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK  BIT(9)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT (BIT(0) | BIT(3))
+
+#define MTK_DP_ENC0_P0_3008		  (ENC0_OFFSET + 0x08)
+#define VIDEO_M_CODE_SW_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_300C		  (ENC0_OFFSET + 0x0C)
+#define VIDEO_M_CODE_SW_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3010	  (ENC0_OFFSET + 0x10)
+#define HTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3014	  (ENC0_OFFSET + 0x14)
+#define VTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3018	  (ENC0_OFFSET + 0x18)
+#define HSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_301C	  (ENC0_OFFSET + 0x1C)
+#define VSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3020	  (ENC0_OFFSET + 0x20)
+#define HWIDTH_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3024	   (ENC0_OFFSET + 0x24)
+#define VHEIGHT_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3028	(ENC0_OFFSET + 0x28)
+#define HSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define HSW_SW_DP_ENC0_P0_SHIFT 0
+#define HSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_302C	(ENC0_OFFSET + 0x2C)
+#define VSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define VSW_SW_DP_ENC0_P0_SHIFT 0
+#define VSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_3030			 (ENC0_OFFSET + 0x30)
+#define HTOTAL_SEL_DP_ENC0_P0_SHIFT		 0
+#define VTOTAL_SEL_DP_ENC0_P0_SHIFT		 BIT(0)
+#define HSTART_SEL_DP_ENC0_P0_SHIFT		 BIT(1)
+#define VSTART_SEL_DP_ENC0_P0_SHIFT		 GENMASK(1, 0)
+#define HWIDTH_SEL_DP_ENC0_P0_SHIFT		 BIT(2)
+#define VHEIGHT_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(2))
+#define HSP_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 1)
+#define HSW_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 0)
+#define VSP_SEL_DP_ENC0_P0_SHIFT		 BIT(3)
+#define VSW_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK	 (BIT(11))
+#define VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT	 (BIT(0) | BIT(1) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK (BIT(12))
+#define VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT	 GENMASK(3, 2)
+
+#define MTK_DP_ENC0_P0_3034 (ENC0_OFFSET + 0x34)
+
+#define MTK_DP_ENC0_P0_3038		  (ENC0_OFFSET + 0x38)
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK  (BIT(11))
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_SHIFT (BIT(0) | BIT(1) | BIT(3))
+
+#define MTK_DP_ENC0_P0_303C		      (ENC0_OFFSET + 0x3C)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT 0
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK     GENMASK(10, 8)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT    BIT(3)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT                                     \
+	(0 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT                                     \
+	(1 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT                                     \
+	(2 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT                                      \
+	(3 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT                                      \
+	(4 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK  GENMASK(14, 12)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT GENMASK(3, 2)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB                                     \
+	(0 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422                                \
+	(1 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420                                \
+	(2 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK	 (BIT(15))
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT GENMASK(3, 0)
+
+#define MTK_DP_ENC0_P0_3040		   (ENC0_OFFSET + 0x40)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_3044	       (ENC0_OFFSET + 0x44)
+#define VIDEO_N_CODE_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3048	       (ENC0_OFFSET + 0x48)
+#define VIDEO_N_CODE_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_304C		      (ENC0_OFFSET + 0x4C)
+#define VBID_VIDEO_MUTE_DP_ENC0_P0_MASK	      BIT(2)
+#define SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK BIT(8)
+
+#define MTK_DP_ENC0_P0_3050		      (ENC0_OFFSET + 0x50)
+#define VIDEO_N_CODE_MN_GEN_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3054		      (ENC0_OFFSET + 0x54)
+#define VIDEO_N_CODE_MN_GEN_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3064	     (ENC0_OFFSET + 0x64)
+#define HDE_NUM_LAST_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3088	      (ENC0_OFFSET + 0x88)
+#define AU_EN_DP_ENC0_P0_MASK	      BIT(6)
+#define AU_EN_DP_ENC0_P0_SHIFT	      GENMASK(2, 1)
+#define AUDIO_8CH_EN_DP_ENC0_P0_MASK  BIT(7)
+#define AUDIO_8CH_SEL_DP_ENC0_P0_MASK BIT(8)
+#define AUDIO_2CH_EN_DP_ENC0_P0_MASK  (BIT(14))
+#define AUDIO_2CH_SEL_DP_ENC0_P0_MASK (BIT(15))
+
+#define MTK_DP_ENC0_P0_308C	    (ENC0_OFFSET + 0x8C)
+#define CH_STATUS_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3090	    (ENC0_OFFSET + 0x90)
+#define CH_STATUS_1_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3094	    (ENC0_OFFSET + 0x94)
+#define CH_STATUS_2_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A0 (ENC0_OFFSET + 0xA0)
+
+#define MTK_DP_ENC0_P0_30A4	  (ENC0_OFFSET + 0xA4)
+#define AU_TS_CFG_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A8 (ENC0_OFFSET + 0xA8)
+
+#define MTK_DP_ENC0_P0_30AC (ENC0_OFFSET + 0xAC)
+
+#define MTK_DP_ENC0_P0_30B0 (ENC0_OFFSET + 0xB0)
+
+#define MTK_DP_ENC0_P0_30B4	  (ENC0_OFFSET + 0xB4)
+#define ISRC_CFG_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define ISRC_CFG_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_30B8 (ENC0_OFFSET + 0xB8)
+
+#define MTK_DP_ENC0_P0_30BC			   (ENC0_OFFSET + 0xBC)
+#define ISRC_CONT_DP_ENC0_P0_MASK		   BIT(0)
+#define ISRC_CONT_DP_ENC0_P0_SHIFT		   0
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK  GENMASK(10, 8)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT BIT(3)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_2                             \
+	(1 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_4                             \
+	(2 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_8                             \
+	(3 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2                             \
+	(5 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_4                             \
+	(6 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_8                             \
+	(7 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+
+#define MTK_DP_ENC0_P0_30D8 (ENC0_OFFSET + 0xD8)
+
+#define MTK_DP_ENC0_P0_312C	 (ENC0_OFFSET + 0x12C)
+#define ASP_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define ASP_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define ASP_HB3_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_3130 (ENC0_OFFSET + 0x130)
+
+#define MTK_DP_ENC0_P0_3138 (ENC0_OFFSET + 0x138)
+
+#define MTK_DP_ENC0_P0_3154	    (ENC0_OFFSET + 0x154)
+#define PGEN_HTOTAL_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3158		  (ENC0_OFFSET + 0x158)
+#define PGEN_HSYNC_RISING_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_315C		       (ENC0_OFFSET + 0x15C)
+#define PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3160		(ENC0_OFFSET + 0x160)
+#define PGEN_HFDE_START_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3164		       (ENC0_OFFSET + 0x164)
+#define PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3168	    (ENC0_OFFSET + 0x168)
+#define PGEN_VTOTAL_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_316C		  (ENC0_OFFSET + 0x16C)
+#define PGEN_VSYNC_RISING_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3170		       (ENC0_OFFSET + 0x170)
+#define PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3174		(ENC0_OFFSET + 0x174)
+#define PGEN_VFDE_START_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3178		       (ENC0_OFFSET + 0x178)
+#define PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_31B0    (ENC0_OFFSET + 0x1B0)
+#define PGEN_PATTERN_SEL_SHIFT BIT(2)
+#define PGEN_PATTERN_SEL_MASK  GENMASK(6, 4)
+
+#define MTK_DP_ENC0_P0_31C8		  (ENC0_OFFSET + 0x1C8)
+#define VSC_EXT_VESA_HB0_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31CC		  (ENC0_OFFSET + 0x1CC)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_VESA_HB3_DP_ENC0_P0_MASK  GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D0		 (ENC0_OFFSET + 0x1D0)
+#define VSC_EXT_CEA_HB0_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31D4		 (ENC0_OFFSET + 0x1D4)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D8		  (ENC0_OFFSET + 0x1D8)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_MASK	  GENMASK(13, 8)
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_SHIFT  BIT(3)
+
+#define MTK_DP_ENC0_P0_31DC	  (ENC0_OFFSET + 0x1DC)
+#define HDR0_CFG_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define HDR0_CFG_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_31E8 (ENC0_OFFSET + 0x1E8)
+
+#define MTK_DP_ENC0_P0_31EC		  (ENC0_OFFSET + 0x1EC)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK  BIT(4)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT BIT(2)
+#define ISRC1_HB3_DP_ENC0_P0_MASK	  GENMASK(15, 8)
+#define ISRC1_HB3_DP_ENC0_P0_SHIFT	  BIT(3)
+
+#define MTK_DP_ENC1_P0_3200 (ENC1_OFFSET + 0x00)
+
+#define MTK_DP_ENC1_P0_3280		(ENC1_OFFSET + 0x80)
+#define SDP_PACKET_TYPE_DP_ENC1_P0_MASK GENMASK(4, 0)
+#define SDP_PACKET_W_DP_ENC1_P0		BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_MASK	BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_SHIFT	(BIT(0) | BIT(2))
+
+#define MTK_DP_ENC1_P0_328C (ENC1_OFFSET + 0x8C)
+
+#define MTK_DP_ENC1_P0_3290 (ENC1_OFFSET + 0x90)
+
+#define MTK_DP_ENC1_P0_32A0 (ENC1_OFFSET + 0xA0)
+
+#define MTK_DP_ENC1_P0_32A4 (ENC1_OFFSET + 0xA4)
+
+#define MTK_DP_ENC1_P0_3300		     (ENC1_OFFSET + 0x100)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC1_P0_3304			  (ENC1_OFFSET + 0x104)
+#define AU_PRTY_REGEN_DP_ENC1_P0_MASK		  BIT(8)
+#define AU_CH_STS_REGEN_DP_ENC1_P0_MASK		  BIT(9)
+#define AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK (BIT(12))
+
+#define MTK_DP_ENC1_P0_3324		  (ENC1_OFFSET + 0x124)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT BIT(3)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX                                       \
+	(0 << AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT)
+
+#define MTK_DP_ENC1_P0_3364			     (ENC1_OFFSET + 0x164)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT 0
+#define FIFO_READ_START_POINT_DP_ENC1_P0_MASK	     GENMASK(15, 12)
+#define FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT	     GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_3368			       (ENC1_OFFSET + 0x168)
+#define VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT 0
+#define VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT	       BIT(2)
+#define SDP_DP13_EN_DP_ENC1_P0_SHIFT		       BIT(3)
+#define BS2BS_MODE_DP_ENC1_P0_MASK		       GENMASK(13, 12)
+#define BS2BS_MODE_DP_ENC1_P0_SHIFT		       GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_33F4 (ENC1_OFFSET + 0x1F4)
+
+#define MTK_DP_TRANS_P0_3400	      (TRANS_OFFSET + 0)
+#define PATTERN1_EN_DP_TRANS_P0_MASK  BIT(12)
+#define PATTERN1_EN_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+#define PATTERN2_EN_DP_TRANS_P0_MASK  BIT(13)
+#define PATTERN3_EN_DP_TRANS_P0_MASK  BIT(14)
+#define PATTERN4_EN_DP_TRANS_P0_MASK  BIT(15)
+
+#define MTK_DP_TRANS_P0_3404	   (TRANS_OFFSET + 0x4)
+#define DP_SCR_EN_DP_TRANS_P0_MASK BIT(0)
+
+#define MTK_DP_TRANS_P0_340C			       (TRANS_OFFSET + 0xC)
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK (BIT(13))
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT                        \
+	(BIT(0) | BIT(2) | BIT(3))
+
+#define MTK_DP_TRANS_P0_3410		    (TRANS_OFFSET + 0x10)
+#define HPD_DEB_THD_DP_TRANS_P0_MASK	    GENMASK(3, 0)
+#define HPD_DEB_THD_DP_TRANS_P0_SHIFT	    0
+#define HPD_INT_THD_DP_TRANS_P0_MASK	    GENMASK(7, 4)
+#define HPD_INT_THD_DP_TRANS_P0_SHIFT	    BIT(2)
+#define HPD_INT_THD_DP_TRANS_P0_LOWER_500US (2 << HPD_INT_THD_DP_TRANS_P0_SHIFT)
+#define HPD_INT_THD_DP_TRANS_P0_UPPER_1100US                                   \
+	(2 << (HPD_INT_THD_DP_TRANS_P0_SHIFT + 2))
+#define HPD_DISC_THD_DP_TRANS_P0_MASK  GENMASK(11, 8)
+#define HPD_DISC_THD_DP_TRANS_P0_SHIFT BIT(3)
+#define HPD_CONN_THD_DP_TRANS_P0_MASK  GENMASK(15, 12)
+#define HPD_CONN_THD_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_3414	(TRANS_OFFSET + 0x14)
+#define HPD_DB_DP_TRANS_P0_MASK BIT(2)
+
+#define MTK_DP_TRANS_P0_3418	      (TRANS_OFFSET + 0x18)
+#define IRQ_CLR_DP_TRANS_P0_MASK      GENMASK(3, 0)
+#define IRQ_MASK_DP_TRANS_P0_MASK     GENMASK(7, 4)
+#define IRQ_MASK_DP_TRANS_P0_SHIFT    BIT(2)
+#define IRQ_MASK_DP_TRANS_P0_DISC_IRQ (BIT(1) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_CONN_IRQ (BIT(2) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_INT_IRQ  (BIT(3) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_STATUS_DP_TRANS_P0_MASK   GENMASK(15, 12)
+#define IRQ_STATUS_DP_TRANS_P0_SHIFT  GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_342C	      (TRANS_OFFSET + 0x2C)
+#define XTAL_FREQ_DP_TRANS_P0_DEFAULT (BIT(0) | BIT(3) | BIT(5) | BIT(6))
+#define XTAL_FREQ_DP_TRANS_P0_MASK    GENMASK(7, 0)
+
+#define MTK_DP_TRANS_P0_3430			   (TRANS_OFFSET + 0x30)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_MASK	   GENMASK(1, 0)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT BIT(1)
+
+#define MTK_DP_TRANS_P0_34A4	   (TRANS_OFFSET + 0xA4)
+#define LANE_NUM_DP_TRANS_P0_MASK  GENMASK(3, 2)
+#define LANE_NUM_DP_TRANS_P0_SHIFT BIT(1)
+
+#define MTK_DP_TRANS_P0_3540		    (TRANS_OFFSET + 0x140)
+#define FEC_EN_DP_TRANS_P0_MASK		    BIT(0)
+#define FEC_EN_DP_TRANS_P0_SHIFT	    0
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK  BIT(3)
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_TRANS_P0_3580			 (TRANS_OFFSET + 0x180)
+#define POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK BIT(8)
+#define POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK BIT(9)
+#define POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK (BIT(10))
+#define POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK (BIT(11))
+
+#define MTK_DP_TRANS_P0_35C4	     (TRANS_OFFSET + 0x1C4)
+#define SW_IRQ_MASK_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35C8	    (TRANS_OFFSET + 0x1C8)
+#define SW_IRQ_CLR_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define SW_IRQ_STATUS_DP_TRANS_P0_MASK	GENMASK(15, 0)
+#define SW_IRQ_STATUS_DP_TRANS_P0_SHIFT 0
+
+#define MTK_DP_TRANS_P0_35D0		     (TRANS_OFFSET + 0x1D0)
+#define SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35F0 (TRANS_OFFSET + 0x1F0)
+
+#define MTK_DP_AUX_P0_360C	       (AUX_OFFSET + 0xC)
+#define AUX_TIMEOUT_THR_AUX_TX_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_AUX_P0_3614		  (AUX_OFFSET + 0x14)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK  GENMASK(6, 0)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3618			 (AUX_OFFSET + 0x18)
+#define AUX_RX_FIFO_FULL_AUX_TX_P0_MASK		 BIT(9)
+#define AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3620		      (AUX_OFFSET + 0x20)
+#define AUX_RD_MODE_AUX_TX_P0_MASK	      BIT(9)
+#define AUX_RX_FIFO_READ_PULSE_TX_P0_MASK     BIT(8)
+#define AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT	      BIT(3)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK  GENMASK(7, 0)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3624		    (AUX_OFFSET + 0x24)
+#define AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3628		 (AUX_OFFSET + 0x28)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_MASK	 GENMASK(9, 0)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT 0
+#define AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE                                     \
+	(BIT(0) << AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT)
+
+#define MTK_DP_AUX_P0_362C		  (AUX_OFFSET + 0x2C)
+#define AUX_NO_LENGTH_AUX_TX_P0_MASK	  BIT(0)
+#define AUX_NO_LENGTH_AUX_TX_P0_SHIFT	  0
+#define AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK BIT(1)
+#define AUX_RESERVED_RW_0_AUX_TX_P0_MASK  GENMASK(15, 2)
+
+#define MTK_DP_AUX_P0_3630		     (AUX_OFFSET + 0x30)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_MASK  BIT(3)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_AUX_P0_3634			(AUX_OFFSET + 0x34)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK	GENMASK(15, 8)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3640			      (AUX_OFFSET + 0x40)
+#define AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK	      BIT(6)
+#define AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT  GENMASK(2, 1)
+#define AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT (BIT(0) | BIT(2))
+#define AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT BIT(2)
+#define AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT	      GENMASK(1, 0)
+#define AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(1)
+#define AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT	      0
+
+#define MTK_DP_AUX_P0_3644		   (AUX_OFFSET + 0x44)
+#define MCU_REQUEST_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3648		       (AUX_OFFSET + 0x48)
+#define MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_AUX_P0_364C		       (AUX_OFFSET + 0x4C)
+#define MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3650		      (AUX_OFFSET + 0x50)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_MASK	      GENMASK(15, 12)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT      GENMASK(3, 2)
+#define PHY_FIFO_RST_AUX_TX_P0_MASK	      BIT(9)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK  BIT(8)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3658	    (AUX_OFFSET + 0x58)
+#define AUX_TX_OV_EN_AUX_TX_P0_MASK BIT(0)
+
+#define MTK_DP_AUX_P0_3690		       (AUX_OFFSET + 0x90)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK  BIT(8)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3704				      (AUX_OFFSET + 0x104)
+#define AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK BIT(1)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK		      BIT(2)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT		      BIT(1)
+
+#define MTK_DP_AUX_P0_3708 (AUX_OFFSET + 0x108)
+
+#define MTK_DP_AUX_P0_37C8	    (AUX_OFFSET + 0x1C8)
+#define MTK_ATOP_EN_AUX_TX_P0_MASK  BIT(0)
+#define MTK_ATOP_EN_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_TOP_PWR_STATE	       (TOP_OFFSET + 0x0)
+#define DP_PWR_STATE_MASK	       GENMASK(1, 0)
+#define DP_PWR_STATE_BANDGAP	       BIT(0)
+#define DP_PWR_STATE_BANDGAP_TPLL      BIT(1)
+#define DP_PWR_STATE_BANDGAP_TPLL_LANE GENMASK(1, 0)
+
+#define MTK_DP_TOP_SWING_EMP	(TOP_OFFSET + 0x4)
+#define DP_TX0_VOLT_SWING_MASK	GENMASK(1, 0)
+#define DP_TX0_VOLT_SWING_SHIFT 0
+#define DP_TX0_PRE_EMPH_MASK	GENMASK(3, 2)
+#define DP_TX0_PRE_EMPH_SHIFT	BIT(1)
+#define DP_TX1_VOLT_SWING_MASK	GENMASK(9, 8)
+#define DP_TX1_VOLT_SWING_SHIFT BIT(3)
+#define DP_TX1_PRE_EMPH_MASK	GENMASK(11, 10)
+#define DP_TX2_VOLT_SWING_MASK	GENMASK(17, 16)
+#define DP_TX2_PRE_EMPH_MASK	GENMASK(19, 18)
+#define DP_TX3_VOLT_SWING_MASK	GENMASK(25, 24)
+#define DP_TX3_PRE_EMPH_MASK	GENMASK(27, 26)
+
+#define MTK_DP_TOP_RESET_AND_PROBE (TOP_OFFSET + 0x20)
+#define SW_RST_B_SHIFT		   0
+#define SW_RST_B_PHYD		   (BIT(4) << SW_RST_B_SHIFT)
+
+#define MTK_DP_TOP_IRQ_STATUS	   (TOP_OFFSET + 0x28)
+#define RGS_IRQ_STATUS_SHIFT	   0
+#define RGS_IRQ_STATUS_TRANSMITTER (BIT(1) << RGS_IRQ_STATUS_SHIFT)
+
+#define MTK_DP_TOP_IRQ_MASK  (TOP_OFFSET + 0x2C)
+#define IRQ_MASK_AUX_TOP_IRQ BIT(2)
+
+#define MTK_DP_TOP_MEM_PD (TOP_OFFSET + 0x38)
+#define MEM_ISO_EN_SHIFT  0
+#define FUSE_SEL_SHIFT	  BIT(1)
+
+#endif /*_MTK_DP_REG_H_*/
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index e25ac61aac08..4e378eb34071 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -906,6 +906,9 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+	&mtk_dp_driver,
+#endif
 	&mtk_drm_platform_driver,
 	&mtk_dsi_driver,
 	&mtk_ethdr_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 8d3ff32b5364..04de9436ea85 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -59,6 +59,9 @@ extern struct platform_driver mtk_disp_ovl_adaptor_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+extern struct platform_driver mtk_dp_driver;
+#endif
 extern struct platform_driver mtk_dsi_driver;
 extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.

It supports the mt8195, the embedded DisplayPort units. It offers
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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/Kconfig       |    8 +
 drivers/gpu/drm/mediatek/Makefile      |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2570 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  570 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |    3 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |    3 +
 6 files changed, 3156 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..a37b6ec9f01e 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -21,6 +21,14 @@ config DRM_MEDIATEK
 	  This driver provides kernel mode setting and
 	  buffer management to userspace.
 
+config DRM_MEDIATEK_DP
+	tristate "DRM DPTX Support for Mediatek SoCs"
+	depends on DRM_MEDIATEK
+	select PHY_MTK_DP
+	select DRM_DP_HELPER
+	help
+	  DRM/KMS Display Port driver for Mediatek SoCs.
+
 config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 3abd27d7c91d..d4d193f60271 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_DRM_MEDIATEK_DP) += 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 000000000000..8eb17ae82bfd
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +-2,2567 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/dp/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/hdmi-codec.h>
+#include <video/videomode.h>
+
+#include "mtk_dp_reg.h"
+
+#define MTK_VDOSYS1_MAX_FRAMERATE 60
+#define MTK_DP_4P1T 4
+#define MTK_DP_HDE 2
+#define MTK_DP_PIX_PER_ADDR 2
+#define MTK_DP_AUX_WAIT_REPLY_COUNT 20
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT 3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT 8
+#define MTK_DP_TRAIN_MAX_ITERATIONS 5
+
+#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_NORMAL,
+	MTK_DP_TRAIN_STATE_DPIDLE,
+};
+
+struct mtk_dp_timings {
+	struct videomode vm;
+
+	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;
+
+	u8  irq_status;
+	int check_cap_count;
+};
+
+/* 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,
+};
+
+//TODO: redundant with DP_MSA_MISC_*_BPC ?
+/* Same values as used for DP Spec MISC0 bits 5,6,7 */
+enum mtk_dp_color_depth {
+	MTK_DP_COLOR_DEPTH_6BIT = 0,
+	MTK_DP_COLOR_DEPTH_8BIT = 1,
+	MTK_DP_COLOR_DEPTH_10BIT = 2,
+	MTK_DP_COLOR_DEPTH_12BIT = 3,
+	MTK_DP_COLOR_DEPTH_16BIT = 4,
+	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
+};
+
+struct mtk_dp_info {
+	enum mtk_dp_color_depth depth;
+	enum dp_pixelformat format;
+	struct mtk_dp_timings timings;
+};
+
+struct dp_cal_data {
+	unsigned int glb_bias_trim;
+	unsigned int clktx_impse;
+
+	unsigned int *ln_tx_impsel_pmos;
+	unsigned int *ln_tx_impsel_nmos;
+};
+
+struct mtk_dp {
+	struct device *dev;
+	struct platform_device *phy_dev;
+	struct phy *phy;
+	struct dp_cal_data cal_data;
+	u8 max_lanes;
+	u8 max_linkrate;
+
+	struct drm_device *drm_dev;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_dp_aux aux;
+
+	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
+
+	struct mtk_dp_info info;
+	enum mtk_dp_state state;
+
+	struct mtk_dp_train_info train_info;
+	enum mtk_dp_train_state train_state;
+	unsigned int input_fmt;
+
+	struct regmap *regs;
+	struct clk *dp_tx_clk;
+
+	bool enabled;
+
+	bool has_fec;
+	/* Protects the mtk_dp struct */
+	struct mutex dp_lock;
+
+	struct drm_connector *conn;
+};
+
+static struct regmap_config mtk_dp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = SEC_OFFSET + 0x90,
+	.name = "mtk-dp-registers",
+};
+
+static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
+{
+	return container_of(b, struct mtk_dp, bridge);
+}
+
+static u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
+{
+	u32 read_val;
+	int ret;
+
+	ret = regmap_read(mtk_dp->regs, offset, &read_val);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to read register 0x%x: %d\n",
+			offset, ret);
+		return 0;
+	}
+
+	return read_val;
+}
+
+static int mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
+{
+	int ret;
+
+	ret = regmap_write(mtk_dp->regs, offset, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to write register 0x%x with value 0x%x: %d\n",
+			offset, val, ret);
+	return ret;
+}
+
+static int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset, u32 val,
+			      u32 mask)
+{
+	int ret;
+
+	ret = regmap_update_bits(mtk_dp->regs, offset, mask, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to update register 0x%x with value 0x%x, mask 0x%x: %d\n",
+			offset, val, mask, ret);
+	return ret;
+}
+
+static int mtk_dp_bulk_16bit_write(struct mtk_dp *mtk_dp, u32 offset, u8 *buf,
+				   size_t length)
+{
+	int i;
+	int ret = 0;
+	int num_regs = (length + 1) / 2;
+
+	/* 2 bytes per register */
+	for (i = 0; i < num_regs; i++) {
+		u32 val = buf[i * 2] |
+			  (i * 2 + 1 < length ? buf[i * 2 + 1] << 8 : 0);
+
+		ret = mtk_dp_write(mtk_dp, offset + i * 4, val);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static unsigned long mtk_dp_sip_atf_call(unsigned int cmd, unsigned int para)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32, cmd, para, 0, 0, 0, 0, 0,
+		      &res);
+
+	pr_debug("[DPTX]%s cmd 0x%x, p1 0x%x, ret 0x%lx-0x%lx", __func__, cmd,
+		 para, res.a0, res.a1);
+	return res.a1;
+}
+
+static int mtk_dp_msa_bypass_disable(struct mtk_dp *mtk_dp)
+{
+	const u16 bits_to_set =
+		BIT(HTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HWIDTH_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VHEIGHT_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSP_SEL_DP_ENC0_P0_SHIFT) | BIT(HSW_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSP_SEL_DP_ENC0_P0_SHIFT) | BIT(VSW_SEL_DP_ENC0_P0_SHIFT);
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3030, bits_to_set,
+			   bits_to_set);
+}
+
+static int mtk_dp_set_msa(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3010, mode.htotal,
+				 HTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3018,
+				 timings->vm.hsync_len + timings->vm.hback_porch,
+			   HSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028,
+				 timings->vm.hsync_len << HSW_SW_DP_ENC0_P0_SHIFT,
+			   HSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028, 0,
+				 HSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3020, timings->vm.hactive,
+				 HWIDTH_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3014, mode.vtotal,
+				 VTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_301C,
+				 timings->vm.vsync_len + timings->vm.vback_porch,
+			   VSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C,
+				 timings->vm.vsync_len << VSW_SW_DP_ENC0_P0_SHIFT,
+			   VSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C, 0,
+				 VSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3024, timings->vm.vactive,
+				 VHEIGHT_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3064, timings->vm.hactive,
+				 HDE_NUM_LAST_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3154, mode.htotal,
+				 PGEN_HTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3158,
+				 timings->vm.hfront_porch,
+			   PGEN_HSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_315C, timings->vm.hsync_len,
+				 PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
+				 timings->vm.hback_porch + timings->vm.hsync_len,
+			   PGEN_HFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3164, timings->vm.hactive,
+				 PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3168, mode.vtotal,
+				 PGEN_VTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_316C,
+				 timings->vm.vfront_porch,
+			   PGEN_VSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3170, timings->vm.vsync_len,
+				 PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
+				 timings->vm.vback_porch + timings->vm.vsync_len,
+			   PGEN_VFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3178, timings->vm.vactive,
+				 PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
+				   enum dp_pixelformat color_format)
+{
+	u32 val;
+	int ret;
+
+	mtk_dp->info.format = color_format;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_format << DP_TEST_COLOR_FORMAT_SHIFT,
+				 DP_TEST_COLOR_FORMAT_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_format) {
+	case DP_PIXELFORMAT_YUV422:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422;
+		break;
+	case DP_PIXELFORMAT_YUV420:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420;
+		break;
+	case DP_PIXELFORMAT_RGB:
+	case DP_PIXELFORMAT_YUV444:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
+		break;
+	case DP_PIXELFORMAT_Y_ONLY:
+	case DP_PIXELFORMAT_RAW:
+	case DP_PIXELFORMAT_RESERVED:
+	default:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
+			 color_format);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_color_depth(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_color_depth color_depth)
+{
+	int ret;
+	u32 val;
+
+	mtk_dp->info.depth = color_depth;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_depth << DP_TEST_BIT_DEPTH_SHIFT,
+				 DP_TEST_BIT_DEPTH_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_depth) {
+	case MTK_DP_COLOR_DEPTH_6BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_8BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_10BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_12BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_16BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_UNKNOWN:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color depth %d\n",
+			 color_depth);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_mn_overwrite_disable(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				  VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_sram_read_start(struct mtk_dp *mtk_dp, u32 val)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				  val << SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT,
+				  SRAM_START_READ_THRD_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_setup_encoder(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				 BIT(VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT),
+				 VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+				 0x20 << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 0x20 << SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3300,
+				 2 << VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT,
+			    VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 4 << FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT,
+			    FIFO_READ_START_POINT_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368,
+			   1 << VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT |
+			   1 << VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT |
+			   BIT(SDP_DP13_EN_DP_ENC1_P0_SHIFT) |
+			   1 << BS2BS_MODE_DP_ENC1_P0_SHIFT);
+
+	return ret;
+}
+
+static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3038, 0,
+				 VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31B0,
+				 4 << PGEN_PATTERN_SEL_SHIFT, PGEN_PATTERN_SEL_MASK);
+
+	return ret;
+}
+
+static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
+{
+	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
+		  HPD_DB_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT));
+	/* Wait for the irq to be cleared */
+	usleep_range(MTK_DP_AUX_WRITE_READ_WAIT_TIME_US,
+		     MTK_DP_AUX_WRITE_READ_WAIT_TIME_US * 2);
+}
+
+static int mtk_dp_aux_set_cmd(struct mtk_dp *mtk_dp, u8 cmd, u32 addr)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3644, cmd,
+				 MCU_REQUEST_COMMAND_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3648, addr,
+				 MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_364C, addr >> 16,
+				 MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_aux_cmd_complete(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+				  BIT(MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT),
+				  MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK |
+				  PHY_FIFO_RST_AUX_TX_P0_MASK |
+				  MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+}
+
+static int mtk_dp_aux_request_ready(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3630,
+				  BIT(AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT),
+				  AUX_TX_REQUEST_READY_AUX_TX_P0_MASK);
+}
+
+static void mtk_dp_aux_fill_write_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				       size_t length)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_AUX_P0_3708, buf, length);
+}
+
+static int mtk_dp_aux_read_rx_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				   size_t length, int read_delay)
+{
+	int ret;
+	int read_pos;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620, 0,
+				 AUX_RD_MODE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+
+	for (read_pos = 0; read_pos < length; read_pos++) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620,
+					 BIT(AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT),
+					 AUX_RX_FIFO_READ_PULSE_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Hardware needs time to update the data */
+		usleep_range(read_delay, read_delay * 2);
+		buf[read_pos] =
+			(u8)(mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3620) &
+			     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK >>
+				     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_set_length(struct mtk_dp *mtk_dp, size_t length)
+{
+	int ret;
+
+	if (length > 0) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+					 (length - 1)
+					 << MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT,
+					 MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C,
+					 BIT(AUX_NO_LENGTH_AUX_TX_P0_SHIFT),
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_wait_for_completion(struct mtk_dp *mtk_dp, bool is_read)
+{
+	int wait_reply = MTK_DP_AUX_WAIT_REPLY_COUNT;
+
+	while (--wait_reply) {
+		u32 aux_irq_status;
+
+		if (is_read) {
+			u32 fifo_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3618);
+
+			if (fifo_status &
+			    (AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK |
+			     AUX_RX_FIFO_FULL_AUX_TX_P0_MASK)) {
+				return 0;
+			}
+		}
+
+		aux_irq_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3640);
+		if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK)
+			return 0;
+
+		if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK)
+			return -ETIMEDOUT;
+
+		/* Give the hardware a chance to reach completion before retrying */
+		usleep_range(100, 500);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
+				  u32 addr, u8 *buf, size_t length)
+{
+	int ret;
+	u32 reply_cmd;
+
+	if (is_read && (length > DP_AUX_MAX_PAYLOAD_BYTES ||
+			(cmd == DP_AUX_NATIVE_READ && !length)))
+		return -EINVAL;
+
+	if (!is_read) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 BIT(AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT),
+					 AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	mtk_dp_aux_set_cmd(mtk_dp, cmd, addr);
+	mtk_dp_aux_set_length(mtk_dp, length);
+
+	if (!is_read) {
+		if (length)
+			mtk_dp_aux_fill_write_fifo(mtk_dp, buf, length);
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_request_ready(mtk_dp);
+
+	ret = mtk_dp_aux_wait_for_completion(mtk_dp, is_read);
+
+	reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
+		    AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
+
+	if (ret || reply_cmd) {
+		u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
+				 AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
+		if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) {
+			drm_err(mtk_dp->drm_dev,
+				"AUX Rx Aux hang, need SW reset\n");
+			return -EIO;
+		}
+
+		mtk_dp_aux_cmd_complete(mtk_dp);
+		mtk_dp_aux_irq_clear(mtk_dp);
+
+		return -ETIMEDOUT;
+	}
+
+	if (!length) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+
+	} else if (is_read) {
+		int read_delay;
+
+		if (cmd == (DP_AUX_I2C_READ | DP_AUX_I2C_MOT) ||
+		    cmd == DP_AUX_I2C_READ)
+			read_delay = 500;
+		else
+			read_delay = 100;
+
+		mtk_dp_aux_read_rx_fifo(mtk_dp, buf, length, read_delay);
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	return 0;
+}
+
+static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
+					  int swing_val, int preemphasis)
+{
+	int ret;
+
+	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
+
+	if (lane_num < 0 || lane_num > 3)
+		return false;
+
+	dev_dbg(mtk_dp->dev,
+		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
+		swing_val, preemphasis);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 swing_val << (DP_TX0_VOLT_SWING_SHIFT + lane_shift),
+				 DP_TX0_VOLT_SWING_MASK << lane_shift);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT + lane_shift),
+				 DP_TX0_PRE_EMPH_MASK << lane_shift);
+
+	return !ret;
+}
+
+static int mtk_dp_reset_swing_pre_emphasis(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP, 0,
+				  DP_TX0_VOLT_SWING_MASK | DP_TX1_VOLT_SWING_MASK |
+				  DP_TX2_VOLT_SWING_MASK |
+				  DP_TX3_VOLT_SWING_MASK |
+				  DP_TX0_PRE_EMPH_MASK | DP_TX1_PRE_EMPH_MASK |
+				  DP_TX2_PRE_EMPH_MASK | DP_TX3_PRE_EMPH_MASK);
+}
+
+static int mtk_dp_fec_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				  enable ? BIT(FEC_EN_DP_TRANS_P0_SHIFT) : 0,
+				  FEC_EN_DP_TRANS_P0_MASK);
+}
+
+static u32 mtk_dp_swirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u32 irq_status = mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_35D0) &
+			 SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, irq_status,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, 0,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+	}
+
+	return irq_status;
+}
+
+static u32 mtk_dp_hwirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u8 irq_status = (mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3418) &
+			 IRQ_STATUS_DP_TRANS_P0_MASK) >>
+			IRQ_STATUS_DP_TRANS_P0_SHIFT;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, irq_status,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, 0,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+	}
+
+	return irq_status;
+}
+
+static int mtk_dp_hwirq_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = enable ? 0 : IRQ_MASK_DP_TRANS_P0_DISC_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_CONN_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_INT_IRQ;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, val,
+			   IRQ_MASK_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_342C,
+				 XTAL_FREQ_DP_TRANS_P0_DEFAULT,
+			   XTAL_FREQ_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				 BIT(FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT),
+			   FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+				 BIT(AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT),
+			   AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_IRQ_MASK, IRQ_MASK_AUX_TOP_IRQ,
+				 IRQ_MASK_AUX_TOP_IRQ);
+
+	return ret;
+}
+
+static void mtk_dp_initialize_hpd_detect_settings(struct mtk_dp *mtk_dp)
+{
+	/* Debounce threshold */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   8 << HPD_DEB_THD_DP_TRANS_P0_SHIFT,
+			   HPD_DEB_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
+			    HPD_INT_THD_DP_TRANS_P0_UPPER_1100US)
+				   << HPD_INT_THD_DP_TRANS_P0_SHIFT,
+			   HPD_INT_THD_DP_TRANS_P0_MASK);
+
+	/* Connect threshold 1.5ms + 5 x 0.1ms = 2ms
+	 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (5 << HPD_DISC_THD_DP_TRANS_P0_SHIFT) |
+				   (5 << HPD_CONN_THD_DP_TRANS_P0_SHIFT),
+			   HPD_DISC_THD_DP_TRANS_P0_MASK |
+				   HPD_CONN_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	/* modify timeout threshold = 1595 [12 : 8] */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_360C, 0x1595,
+				 AUX_TIMEOUT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3658, 0,
+				 AUX_TX_OV_EN_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 25 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3634,
+				 25 << AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT,
+			   AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 13 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3614,
+				 13 << AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT,
+			   AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_37C8,
+				 BIT(MTK_ATOP_EN_AUX_TX_P0_SHIFT),
+			   MTK_ATOP_EN_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 VBID_VIDEO_MUTE_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	mtk_dp_set_color_format(mtk_dp, DP_PIXELFORMAT_RGB);
+	mtk_dp_set_color_depth(mtk_dp, MTK_DP_COLOR_DEPTH_8BIT);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3368,
+				 1 << BS2BS_MODE_DP_ENC1_P0_SHIFT,
+			   BS2BS_MODE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* dp tx encoder reset all sw */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
+				 BIT(DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT),
+			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				 DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_digital_sw_reset(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C,
+				 BIT(DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT),
+			   DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C, 0,
+				 DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_lanes(struct mtk_dp *mtk_dp, int lanes)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35F0,
+				 lanes == 0 ? 0 : BIT(3), BIT(3) | BIT(2));
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, lanes,
+				 LANE_NUM_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4,
+				 lanes << LANE_NUM_DP_TRANS_P0_SHIFT,
+			   LANE_NUM_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int link_rate_to_mb_per_s(struct mtk_dp *mtk_dp,
+				 enum mtk_dp_linkrate linkrate)
+{
+	switch (linkrate) {
+	case MTK_DP_LINKRATE_RBR:
+		return 1620;
+	case MTK_DP_LINKRATE_HBR:
+		return 2700;
+	case MTK_DP_LINKRATE_HBR2:
+		return 5400;
+	case MTK_DP_LINKRATE_HBR3:
+		return 8100;
+	default:
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, unknown linkrate %d\n",
+			linkrate);
+		return -EINVAL;
+	}
+}
+
+static u32 check_cal_data_valid(struct mtk_dp *mtk_dp, u32 min, u32 max, u32 val, u32 default_val)
+{
+	if (val < min || val > max)
+		dev_warn(mtk_dp->dev, "Invalid calibration data: %d (< %d || > %d), returning default %d\n",
+			 val, min, max, default_val);
+		return default_val;
+
+	return val;
+}
+
+static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
+{
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+	struct device *dev = mtk_dp->dev;
+	struct nvmem_cell *cell;
+	u32 *buf;
+	size_t len;
+
+	cell = nvmem_cell_get(dev, "dp_calibration_data");
+	if (IS_ERR(cell)) {
+		dev_err(dev,
+			"Error: Failed to get nvmem cell dp_calibration_data\n");
+		return PTR_ERR(cell);
+	}
+
+	buf = (u32 *)nvmem_cell_read(cell, &len);
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) {
+		dev_err(dev,
+			"Error: Failed to read nvmem_cell_read fail len %ld\n",
+			(len / sizeof(u32)));
+		return PTR_ERR(buf);
+	}
+
+	cal_data->ln_tx_impsel_nmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_nmos)
+		return -ENOMEM;
+
+	cal_data->ln_tx_impsel_pmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_pmos)
+		return -ENOMEM;
+
+	cal_data->glb_bias_trim =
+		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+	cal_data->clktx_impse =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int mtk_dp_set_cal_data(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_DPAUX_TX,
+				 cal_data->clktx_impse << 20, RG_CKM_PT0_CKTX_IMPSEL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_BIAS_GEN_00,
+				 cal_data->glb_bias_trim << 16,
+			   RG_XTP_GLB_BIAS_INTR_CTRL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_pmos[0] << 12,
+			   RG_XTP_LN0_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_nmos[0] << 16,
+			   RG_XTP_LN0_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_pmos[1] << 12,
+			   RG_XTP_LN1_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_nmos[1] << 16,
+			   RG_XTP_LN1_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_pmos[2] << 12,
+			   RG_XTP_LN2_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_nmos[2] << 16,
+			   RG_XTP_LN2_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_pmos[3] << 12,
+			   RG_XTP_LN3_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_nmos[3] << 16,
+			   RG_XTP_LN3_TX_IMPSEL_NMOS);
+
+	return ret;
+}
+
+static int mtk_dp_phy_configure(struct mtk_dp *mtk_dp,
+				enum mtk_dp_linkrate link_rate, int lane_count)
+{
+	int ret;
+	union phy_configure_opts phy_opts = {
+		.dp = {
+			.link_rate = link_rate_to_mb_per_s(mtk_dp, link_rate),
+			.set_rate = 1,
+			.lanes = lane_count,
+			.set_lanes = 1,
+			.ssc = mtk_dp->train_info.sink_ssc,
+		}
+		};
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP,
+				 DP_PWR_STATE_MASK);
+	if (ret)
+		return ret;
+
+	ret = phy_configure(mtk_dp->phy, &phy_opts);
+
+	if (ret)
+		return ret;
+
+	mtk_dp_set_cal_data(mtk_dp);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_idle_pattern(struct mtk_dp *mtk_dp, bool enable)
+{
+	const u32 val = POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK;
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3580, enable ? val : 0, val);
+}
+
+static int mtk_dp_train_set_pattern(struct mtk_dp *mtk_dp, int pattern)
+{
+	int ret;
+
+	if (pattern < 0 || pattern > 4) {
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, no such pattern %d\n", pattern);
+		return -EINVAL;
+	}
+
+	if (pattern == 1) { /* TPS1 */
+		ret = mtk_dp_set_idle_pattern(mtk_dp, false);
+		if (ret)
+			return ret;
+	}
+
+	return mtk_dp_update_bits(mtk_dp,
+			   MTK_DP_TRANS_P0_3400,
+			   pattern ? BIT(pattern - 1) << PATTERN1_EN_DP_TRANS_P0_SHIFT : 0,
+			   PATTERN1_EN_DP_TRANS_P0_MASK | PATTERN2_EN_DP_TRANS_P0_MASK |
+			   PATTERN3_EN_DP_TRANS_P0_MASK |
+			   PATTERN4_EN_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_set_enhanced_frame_mode(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
+			   enable ? BIT(ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT) : 0,
+			   ENHANCED_FRAME_EN_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3404,
+			   enable ? DP_SCR_EN_DP_TRANS_P0_MASK : 0,
+			   DP_SCR_EN_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
+
+	if (enable)
+		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
+			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+}
+
+static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, 0,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	/* Wait for power enable */
+	usleep_range(10, 200);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, SW_RST_B_PHYD,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL,
+			   DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
+			   DA_CKM_CKTX0_EN_FORCE_EN | DA_CKM_BIAS_LPF_EN_FORCE_VAL |
+		     DA_CKM_BIAS_EN_FORCE_VAL |
+		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
+		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
+
+	if (ret)
+		return ret;
+
+	/* Disable RX */
+	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
+			   0x550 | BIT(FUSE_SEL_SHIFT) | BIT(MEM_ISO_EN_SHIFT));
+
+	return ret;
+}
+
+static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
+{
+	mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR2;
+	mtk_dp->train_info.lane_count = mtk_dp->max_lanes;
+	mtk_dp->train_info.irq_status = 0;
+	mtk_dp->train_info.cable_plugged_in = false;
+	mtk_dp->train_info.cable_state_change = false;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	mtk_dp->state = MTK_DP_STATE_INITIAL;
+
+	mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+	mtk_dp->info.depth = MTK_DP_COLOR_DEPTH_8BIT;
+	memset(&mtk_dp->info.timings, 0, sizeof(struct mtk_dp_timings));
+	mtk_dp->info.timings.frame_rate = 60;
+
+	mtk_dp->has_fec = false;
+}
+
+static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
+{
+	u32 sram_read_start = MTK_DP_TBC_BUF_READ_START_ADDR;
+
+	if (mtk_dp->train_info.lane_count > 0) {
+		sram_read_start = min_t(u32,
+					MTK_DP_TBC_BUF_READ_START_ADDR,
+					mtk_dp->info.timings.vm.hactive /
+					mtk_dp->train_info.lane_count /
+					MTK_DP_4P1T / MTK_DP_HDE / MTK_DP_PIX_PER_ADDR);
+		mtk_dp_set_sram_read_start(mtk_dp, sram_read_start);
+	}
+
+	mtk_dp_setup_encoder(mtk_dp);
+}
+
+static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
+{
+	u8 target_frame_rate = 60;
+	u32 target_pixel_clk;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.frame_rate > 0) {
+		target_frame_rate = mtk_dp->info.timings.frame_rate;
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	} else if (mtk_dp->info.timings.pix_rate_khz > 0) {
+		target_pixel_clk = mtk_dp->info.timings.pix_rate_khz * 1000;
+	} else {
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	}
+
+	mtk_dp->info.timings.pix_rate_khz = target_pixel_clk / 1000;
+}
+
+static void mtk_dp_set_tx_out(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_msa_bypass_disable(mtk_dp);
+	mtk_dp_calculate_pixrate(mtk_dp);
+	mtk_dp_pg_disable(mtk_dp);
+	mtk_dp_setup_tu(mtk_dp);
+}
+
+static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
+{
+	ssize_t ret;
+	u8 sink_count;
+	bool locked;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+	u32 sink_count_reg = DP_SINK_COUNT_ESI;
+	u32 link_status_reg = DP_LANE0_1_STATUS;
+
+	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg, &sink_count);
+	if (ret < 0) {
+		drm_err(mtk_dp->drm_dev, "Read sink count failed: %ld\n", ret);
+		return ret;
+	}
+
+	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg, link_status,
+			       sizeof(link_status));
+	if (!ret) {
+		drm_err(mtk_dp->drm_dev, "Read link status failed: %ld\n",
+			ret);
+		return ret;
+	}
+
+	locked = drm_dp_channel_eq_ok(link_status,
+				      mtk_dp->train_info.lane_count);
+	if (!locked && mtk_dp->train_state > MTK_DP_TRAIN_STATE_TRAINING_PRE)
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+
+	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR,
+				   DP_REMOTE_CONTROL_COMMAND_PENDING);
+
+	if (DP_GET_SINK_COUNT(sink_count) &&
+	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
+		mtk_dp->train_info.check_cap_count = 0;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+		msleep(20);
+	}
+
+	return 0;
+}
+
+static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
+					  u8 dpcd_adjust_req[2])
+{
+	int lane;
+
+	for (lane = 0; lane < lanes; ++lane) {
+		u8 val;
+		u8 swing;
+		u8 preemphasis;
+		int index = lane / 2;
+		int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
+
+		swing = (dpcd_adjust_req[index] >> shift) &
+			DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
+		preemphasis = ((dpcd_adjust_req[index] >> shift) &
+			       DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
+			      DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
+		val = swing << DP_TRAIN_VOLTAGE_SWING_SHIFT |
+		      preemphasis << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+		if (swing == DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
+			val |= DP_TRAIN_MAX_SWING_REACHED;
+		if (preemphasis == 3)
+			val |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+		mtk_dp_set_swing_pre_emphasis(mtk_dp, lane, swing, preemphasis);
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_LANE0_SET + lane,
+				   val);
+	}
+}
+
+static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
+				    u8 link_status[DP_LINK_STATUS_SIZE])
+{
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
+			 DP_LINK_STATUS_SIZE);
+}
+
+static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
+			      u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, false);
+	if (ret)
+		return ret;
+
+	if (*status_control == 0) {
+		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
+		if (ret)
+			return ret;
+
+		val = DP_LINK_SCRAMBLING_DISABLE |
+			DP_TRAINING_PATTERN_1;
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_1);
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 1;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
+					       mtk_dp->rx_cap);
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (drm_dp_clock_recovery_ok(link_status,
+				     target_lane_count)) {
+		mtk_dp->train_info.cr_done = true;
+		*iteration_count = 1;
+		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
+		return 0;
+	} else if (*prev_lane_adjust == link_status[4]) {
+		(*iteration_count)++;
+		if (*prev_lane_adjust & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
+			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
+			return -EINVAL;
+		}
+	} else {
+		*prev_lane_adjust = link_status[4];
+	}
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8 target_linkrate,
+				u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	if (*status_control == 1) {
+		if (mtk_dp->train_info.tps4) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_TRAINING_PATTERN_4;
+		} else if (mtk_dp->train_info.tps3) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_3;
+		} else {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_2;
+		}
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				val);
+
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 2;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
+					   mtk_dp->rx_cap);
+
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (!drm_dp_clock_recovery_ok(link_status,
+				      target_lane_count)) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
+		return -EINVAL;
+	}
+
+	if (drm_dp_channel_eq_ok(link_status,
+				 target_lane_count)) {
+		mtk_dp->train_info.eq_done = true;
+		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
+		return 0;
+	}
+
+	if (*prev_lane_adjust == link_status[4])
+		(*iteration_count)++;
+	else
+		*prev_lane_adjust = link_status[4];
+
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_flow(struct mtk_dp *mtk_dp, u8 target_link_rate,
+			     u8 target_lane_count)
+{
+	u8 lane_adjust[2] = {};
+	bool pass_tps1 = false;
+	bool pass_tps2_3 = false;
+	int train_retries;
+	int status_control;
+	int iteration_count;
+	int ret;
+	u8 prev_lane_adjust;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LINK_BW_SET, target_link_rate);
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count | DP_LANE_COUNT_ENHANCED_FRAME_EN);
+
+	if (mtk_dp->train_info.sink_ssc)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DOWNSPREAD_CTRL,
+				   DP_SPREAD_AMP_0_5);
+
+	train_retries = 0;
+	status_control = 0;
+	iteration_count = 1;
+	prev_lane_adjust = 0xFF;
+
+	mtk_dp_set_lanes(mtk_dp, target_lane_count / 2);
+	ret = mtk_dp_phy_configure(mtk_dp, target_link_rate, target_lane_count);
+	if (ret)
+		return -EINVAL;
+
+	dev_dbg(mtk_dp->dev,
+		"Link train target_link_rate = 0x%x, target_lane_count = 0x%x\n",
+		target_link_rate, target_lane_count);
+
+	do {
+		train_retries++;
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    ((mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) !=
+		     0x0)) {
+			return -ENODEV;
+		}
+
+		if (mtk_dp->train_state < MTK_DP_TRAIN_STATE_TRAINING)
+			return -EAGAIN;
+
+		if (!pass_tps1) {
+			ret = mtk_dp_train_tps_1(mtk_dp, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps1 = true;
+				train_retries = 0;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		} else {
+			ret = mtk_dp_train_tps_2_3(mtk_dp, target_link_rate, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps2_3 = true;
+				break;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		}
+
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_ADJUST_REQUEST_LANE0_1,
+				 lane_adjust, sizeof(lane_adjust));
+		mtk_dp_train_update_swing_pre(mtk_dp, target_lane_count,
+					      lane_adjust);
+	} while (train_retries < MTK_DP_TRAIN_RETRY_LIMIT &&
+		 iteration_count < MTK_DP_TRAIN_MAX_ITERATIONS);
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET,
+			   DP_TRAINING_PATTERN_DISABLE);
+	ret = mtk_dp_train_set_pattern(mtk_dp, 0);
+	if (ret)
+		return -EINVAL;
+
+	if (!pass_tps2_3)
+		return -ETIMEDOUT;
+
+	mtk_dp->train_info.link_rate = target_link_rate;
+	mtk_dp->train_info.lane_count = target_lane_count;
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, true);
+	if (ret)
+		return ret;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count |
+				   DP_LANE_COUNT_ENHANCED_FRAME_EN);
+	ret = mtk_dp_set_enhanced_frame_mode(mtk_dp, true);
+
+	return ret;
+}
+
+static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+{
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+	u8 val;
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	if (!mtk_dp_plug_state(mtk_dp))
+		return false;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
+	/* Wait for power on */
+	usleep_range(2000, 5000);
+
+	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+
+	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap), sizeof(buf)));
+	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &= DP_TRAINING_AUX_RD_MASK;
+
+	train_info->link_rate =
+		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp->max_linkrate]);
+	train_info->lane_count =
+		min_t(int, mtk_dp->max_lanes, drm_dp_max_lane_count(buf));
+
+	train_info->tps3 = drm_dp_tps3_supported(buf);
+	train_info->tps4 = drm_dp_tps4_supported(buf);
+
+	train_info->sink_ssc =
+		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
+
+	train_info->sink_ssc = false;
+
+	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
+	if (val & DP_MST_CAP) {
+		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
+		drm_dp_dpcd_readb(&mtk_dp->aux,
+				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, &val);
+		if (val)
+			drm_dp_dpcd_writeb(&mtk_dp->aux,
+					   DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
+					   val);
+	}
+
+	return true;
+}
+
+static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
+{
+	phy_reset(mtk_dp->phy);
+	mtk_dp_reset_swing_pre_emphasis(mtk_dp);
+}
+
+static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+	u8 lane_count;
+	u8 link_rate;
+	u8 train_limit;
+	u8 max_link_rate;
+	u8 plug_wait;
+
+	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait > 0;
+	     --plug_wait)
+		/* Avoid short pulses on the HPD isr */
+		usleep_range(1000, 5000);
+	if (plug_wait == 0) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+		return -ENODEV;
+	}
+
+	link_rate = mtk_dp->rx_cap[1];
+	lane_count = mtk_dp->rx_cap[2] & 0x1F;
+
+	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate, link_rate);
+	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes, lane_count);
+	link_rate = mtk_dp->train_info.link_rate;
+	lane_count = mtk_dp->train_info.lane_count;
+
+	switch (link_rate) {
+	case MTK_DP_LINKRATE_RBR:
+	case MTK_DP_LINKRATE_HBR:
+	case MTK_DP_LINKRATE_HBR2:
+	case MTK_DP_LINKRATE_HBR25:
+	case MTK_DP_LINKRATE_HBR3:
+		break;
+	default:
+		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
+		break;
+	};
+
+	max_link_rate = link_rate;
+	for (train_limit = 6; train_limit > 0; train_limit--) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+
+		mtk_dp_train_change_mode(mtk_dp);
+		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
+		if (ret)
+			return ret;
+
+		if (!mtk_dp->train_info.cr_done) {
+			switch (link_rate) {
+			case MTK_DP_LINKRATE_RBR:
+				lane_count = lane_count / 2;
+				link_rate = max_link_rate;
+				if (lane_count == 0) {
+					mtk_dp->train_state =
+						MTK_DP_TRAIN_STATE_DPIDLE;
+					return -EIO;
+				}
+				break;
+			case MTK_DP_LINKRATE_HBR:
+				link_rate = MTK_DP_LINKRATE_RBR;
+				break;
+			case MTK_DP_LINKRATE_HBR2:
+				link_rate = MTK_DP_LINKRATE_HBR;
+				break;
+			case MTK_DP_LINKRATE_HBR3:
+				link_rate = MTK_DP_LINKRATE_HBR2;
+				break;
+			default:
+				return -EINVAL;
+			};
+		} else if (!mtk_dp->train_info.eq_done) {
+			if (lane_count == 0)
+				return -EIO;
+
+			lane_count /= 2;
+		} else {
+			break;
+		}
+	}
+
+	if (train_limit == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+//TODO: check drm_dp_helpers for duplicated code
+
+static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	if (enable) {
+		mtk_dp_set_tx_out(mtk_dp);
+		mtk_dp_video_mute(mtk_dp, false);
+	} else {
+		mtk_dp_video_mute(mtk_dp, true);
+	}
+}
+
+static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_mn_overwrite_disable(mtk_dp);
+
+	mtk_dp_set_msa(mtk_dp);
+
+	mtk_dp_set_color_depth(mtk_dp, mtk_dp->info.depth);
+	mtk_dp_set_color_format(mtk_dp, mtk_dp->info.format);
+}
+
+static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
+{
+	switch (mtk_dp->state) {
+	case MTK_DP_STATE_INITIAL:
+		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp->state = MTK_DP_STATE_IDLE;
+		break;
+
+	case MTK_DP_STATE_IDLE:
+		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
+			mtk_dp->state = MTK_DP_STATE_PREPARE;
+		break;
+
+	case MTK_DP_STATE_PREPARE:
+		mtk_dp_video_config(mtk_dp);
+		mtk_dp_video_enable(mtk_dp, true);
+
+		mtk_dp->state = MTK_DP_STATE_NORMAL;
+		break;
+
+	case MTK_DP_STATE_NORMAL:
+		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
+			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp->state = MTK_DP_STATE_IDLE;
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
+{
+	bool training_done = false;
+	short max_retry = 50;
+	int ret = 0;
+
+	do {
+		switch (mtk_dp->train_state) {
+		case MTK_DP_TRAIN_STATE_STARTUP:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKCAP:
+			if (mtk_dp_parse_capabilities(mtk_dp)) {
+				mtk_dp->train_info.check_cap_count = 0;
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+			} else {
+				mtk_dp->train_info.check_cap_count++;
+
+				if (mtk_dp->train_info.check_cap_count >
+				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT) {
+					mtk_dp->train_info.check_cap_count = 0;
+					mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+					ret = -ETIMEDOUT;
+				}
+			}
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKEDID:
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING:
+			ret = mtk_dp_train_start(mtk_dp);
+			if (ret == 0) {
+				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
+				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
+			} else if (ret != -EAGAIN) {
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+			}
+			break;
+		case MTK_DP_TRAIN_STATE_NORMAL:
+			mtk_dp_state_handler(mtk_dp);
+			training_done = true;
+			break;
+		case MTK_DP_TRAIN_STATE_DPIDLE:
+			break;
+		default:
+			break;
+		}
+
+		if (ret) {
+			if (ret == -EAGAIN)
+				continue;
+			/*
+			 * If we get any other error number, it doesn't
+			 * make any sense to keep iterating.
+			 */
+			break;
+		}
+	} while (!training_done || --max_retry);
+
+	return ret;
+}
+
+static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_set_idle_pattern(mtk_dp, true);
+	mtk_dp_initialize_priv_data(mtk_dp);
+
+	mtk_dp_initialize_settings(mtk_dp);
+	mtk_dp_initialize_aux_settings(mtk_dp);
+	mtk_dp_initialize_digital_settings(mtk_dp);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690,
+			   BIT(RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT),
+			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK);
+	mtk_dp_initialize_hpd_detect_settings(mtk_dp);
+
+	mtk_dp_digital_sw_reset(mtk_dp);
+}
+
+static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	int event;
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+
+	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected :
+						  connector_status_disconnected;
+
+	if (event < 0)
+		return IRQ_HANDLED;
+
+	if (mtk_dp->drm_dev) {
+		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
+		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
+	}
+
+	if (mtk_dp->train_info.cable_state_change) {
+		mtk_dp->train_info.cable_state_change = false;
+
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    !mtk_dp_plug_state(mtk_dp)) {
+			mtk_dp_video_mute(mtk_dp, true);
+
+			mtk_dp_initialize_priv_data(mtk_dp);
+			mtk_dp_set_idle_pattern(mtk_dp, true);
+			if (mtk_dp->has_fec)
+				mtk_dp_fec_enable(mtk_dp, false);
+
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL,
+					   DP_PWR_STATE_MASK);
+		} else {
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL_LANE,
+					   DP_PWR_STATE_MASK);
+			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+			mtk_dp->train_info.link_rate =
+				min_t(int, mtk_dp->max_linkrate,
+				      buf[mtk_dp->max_linkrate]);
+			mtk_dp->train_info.lane_count =
+				min_t(int, mtk_dp->max_lanes,
+				      drm_dp_max_lane_count(buf));
+		}
+	}
+
+	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
+		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
+		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
+		mtk_dp_hpd_sink_event(mtk_dp);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
+{
+	bool connected;
+	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
+	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	train_info->irq_status |= hwirq_status | swirq_status;
+
+	if (!train_info->irq_status)
+		return IRQ_HANDLED;
+
+	connected = mtk_dp_plug_state(mtk_dp);
+	if (connected || !train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+	else if (!connected || train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;
+
+	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+		train_info->cable_plugged_in = true;
+	} else {
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+		train_info->cable_plugged_in = false;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	}
+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	u32 irq_status;
+
+	irq_status = mtk_dp_read(mtk_dp, MTK_DP_TOP_IRQ_STATUS);
+
+	if (!irq_status)
+		return IRQ_HANDLED;
+
+	if (irq_status & RGS_IRQ_STATUS_TRANSMITTER)
+		return mtk_dp_hpd_isr_handler(mtk_dp);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
+			   struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	mtk_dp->regs = devm_regmap_init_mmio(dev, base, &mtk_dp_regmap_config);
+	if (IS_ERR(mtk_dp->regs))
+		return PTR_ERR(mtk_dp->regs);
+
+	mtk_dp->dp_tx_clk = devm_clk_get(dev, "faxi");
+	if (IS_ERR(mtk_dp->dp_tx_clk)) {
+		dev_err(dev, "Failed to get dptx clock: %d\n", ret);
+		mtk_dp->dp_tx_clk = NULL;
+		return PTR_ERR(mtk_dp->dp_tx_clk);
+	}
+
+	ret = device_property_read_u8(dev, "max-lanes", &mtk_dp->max_lanes);
+	if (ret)
+		return ret;
+
+	ret = device_property_read_u8(dev, "max-linkrate", &mtk_dp->max_linkrate);
+
+	return ret;
+}
+
+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 enabled = mtk_dp->enabled;
+	struct edid *new_edid = NULL;
+
+//TODO: refcount enabled so that we don't have any surprises...
+
+	if (!enabled)
+		drm_bridge_chain_pre_enable(bridge);
+
+	if (mtk_dp_plug_state(mtk_dp))
+		new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc);
+
+	if (!enabled)
+		drm_bridge_chain_post_disable(bridge);
+
+	return new_edid;
+}
+
+static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+				   struct drm_dp_aux_msg *msg)
+{
+	struct mtk_dp *mtk_dp;
+	bool is_read;
+	u8 request;
+	size_t accessed_bytes = 0;
+	int ret = 0;
+
+	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
+
+	if (!mtk_dp->train_info.cable_plugged_in ||
+	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+		return -EAGAIN;
+	}
+
+	switch (msg->request) {
+	case DP_AUX_I2C_MOT:
+	case DP_AUX_I2C_WRITE:
+	case DP_AUX_NATIVE_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
+		request = msg->request & ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
+		is_read = false;
+		break;
+	case DP_AUX_I2C_READ:
+	case DP_AUX_NATIVE_READ:
+	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
+		request = msg->request;
+		is_read = true;
+		break;
+	default:
+		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
+			msg->request);
+		return -EINVAL;
+	}
+
+	if (msg->size == 0) {
+		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
+					     msg->address + accessed_bytes,
+					     msg->buffer + accessed_bytes, 0);
+	} else {
+		while (accessed_bytes < msg->size) {
+			size_t to_access =
+				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
+				      msg->size - accessed_bytes);
+
+			ret = mtk_dp_aux_do_transfer(mtk_dp,
+						     is_read, request,
+							 msg->address + accessed_bytes,
+							 msg->buffer + accessed_bytes,
+							 to_access);
+
+			if (ret) {
+				drm_info(mtk_dp->drm_dev,
+					 "Failed to do AUX transfer: %d\n", ret);
+				break;
+			}
+			accessed_bytes += to_access;
+		}
+	}
+
+	if (ret) {
+		msg->reply = DP_AUX_NATIVE_REPLY_NACK | DP_AUX_I2C_REPLY_NACK;
+		return ret;
+	}
+
+	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
+	return msg->size;
+}
+
+static void mtk_dp_poweroff(struct mtk_dp *mtk_dp)
+{
+	mutex_lock(&mtk_dp->dp_lock);
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+	mtk_dp_power_disable(mtk_dp);
+	phy_exit(mtk_dp->phy);
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+
+	mutex_unlock(&mtk_dp->dp_lock);
+}
+
+static int mtk_dp_poweron(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->dp_lock);
+
+	ret = clk_prepare_enable(mtk_dp->dp_tx_clk);
+	if (ret < 0) {
+		dev_err(mtk_dp->dev, "Fail to enable clock: %d\n", ret);
+		goto err;
+	}
+	ret = phy_init(mtk_dp->phy);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to initialize phy: %d\n", ret);
+		goto err_phy_init;
+	}
+	ret = mtk_dp_phy_configure(mtk_dp, MTK_DP_LINKRATE_RBR, 1);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to configure phy: %d\n", ret);
+		goto err_phy_config;
+	}
+
+	mtk_dp_init_port(mtk_dp);
+	ret = mtk_dp_power_enable(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+
+err_phy_config:
+	phy_exit(mtk_dp->phy);
+err_phy_init:
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+err:
+	mutex_unlock(&mtk_dp->dp_lock);
+	return ret;
+}
+
+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;
+
+	ret = mtk_dp_poweron(mtk_dp);
+	if (ret)
+		return ret;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mtk_dp->dev, "Driver does not provide a connector!");
+		return -EINVAL;
+	}
+
+	if (mtk_dp->next_bridge) {
+		ret = drm_bridge_attach(bridge->encoder, mtk_dp->next_bridge,
+					&mtk_dp->bridge, flags);
+		if (ret) {
+			drm_warn(mtk_dp->drm_dev,
+				 "Failed to attach external bridge: %d\n", ret);
+			return ret;
+		}
+	}
+
+	mtk_dp->drm_dev = bridge->dev;
+
+	return 0;
+}
+
+static void mtk_dp_bridge_detach(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->drm_dev = NULL;
+}
+
+static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp->state = MTK_DP_STATE_IDLE;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+	mtk_dp->enabled = false;
+	/* Ensure the sink is muted before powering off */
+	msleep(100);
+	mtk_dp_poweroff(mtk_dp);
+}
+
+static void mtk_dp_parse_drm_mode_timings(struct mtk_dp *mtk_dp,
+					  struct drm_display_mode *mode)
+{
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_to_videomode(mode, &timings->vm);
+	timings->frame_rate = drm_mode_vrefresh(mode);
+}
+
+static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
+					struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->conn = drm_atomic_get_new_connector_for_encoder(old_state->base.state,
+								bridge->encoder);
+	if (!mtk_dp->conn) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector is missing\n");
+		return;
+	}
+
+	/* Training */
+	if (mtk_dp_train_handler(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev, "Training failed\n");
+		return;
+	}
+
+	mtk_dp->enabled = true;
+}
+
+static enum drm_mode_status
+mtk_dp_bridge_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+	u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24;
+
+	if (rx_linkrate * mtk_dp->train_info.lane_count < mode->clock * bpp / 8)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock > 600000)
+		return MODE_CLOCK_HIGH;
+
+	if ((mode->clock * 1000) / (mode->htotal * mode->vtotal) > MTK_VDOSYS1_MAX_FRAMERATE)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *output_fmts;
+
+	*num_output_fmts = 0;
+	output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL);
+	if (!output_fmts)
+		return NULL;
+	*num_output_fmts = 1;
+	output_fmts[0] = MEDIA_BUS_FMT_FIXED;
+	return output_fmts;
+}
+
+static const u32 mt8195_input_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *input_fmts;
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+	struct drm_display_info *display_info =
+		&conn_state->connector->display_info;
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+
+	*num_input_fmts = 0;
+
+	if (((rx_linkrate * mtk_dp->train_info.lane_count) <
+	     (mode->clock * 24 / 8)) &&
+	    ((rx_linkrate * mtk_dp->train_info.lane_count) >
+	     (mode->clock * 16 / 8)) &&
+	    (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+		input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+		*num_input_fmts = 1;
+		input_fmts[0] = MEDIA_BUS_FMT_YUYV8_1X16;
+	} else {
+		input_fmts = kcalloc(ARRAY_SIZE(mt8195_input_fmts), sizeof(*input_fmts),
+				     GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+
+		*num_input_fmts = ARRAY_SIZE(mt8195_input_fmts);
+		memcpy(input_fmts, mt8195_input_fmts, sizeof(mt8195_input_fmts));
+	}
+
+	return input_fmts;
+}
+
+static int mtk_dp_bridge_atomic_check(struct drm_bridge *bridge,
+				      struct drm_bridge_state *bridge_state,
+				      struct drm_crtc_state *crtc_state,
+				      struct drm_connector_state *conn_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_crtc *crtc = conn_state->crtc;
+	unsigned int input_bus_format;
+
+	input_bus_format = bridge_state->input_bus_cfg.format;
+
+	dev_dbg(mtk_dp->dev, "input format 0x%04x, output format 0x%04x\n",
+		bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
+
+	mtk_dp->input_fmt = input_bus_format;
+	if (mtk_dp->input_fmt == MEDIA_BUS_FMT_YUYV8_1X16)
+		mtk_dp->info.format = DP_PIXELFORMAT_YUV422;
+	else
+		mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+
+	if (!crtc) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector state doesn't have a crtc\n");
+		return -EINVAL;
+	}
+
+	mtk_dp_parse_drm_mode_timings(mtk_dp, &crtc_state->adjusted_mode);
+	if (!mtk_dp_parse_capabilities(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as nothing is plugged in\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
+	.atomic_check = mtk_dp_bridge_atomic_check,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_get_output_bus_fmts = mtk_dp_bridge_atomic_get_output_bus_fmts,
+	.atomic_get_input_bus_fmts = mtk_dp_bridge_atomic_get_input_bus_fmts,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.attach = mtk_dp_bridge_attach,
+	.detach = mtk_dp_bridge_detach,
+	.atomic_enable = mtk_dp_bridge_atomic_enable,
+	.atomic_disable = mtk_dp_bridge_atomic_disable,
+	.mode_valid = mtk_dp_bridge_mode_valid,
+	.get_edid = mtk_dp_get_edid,
+};
+
+static int mtk_dp_probe(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp;
+	struct device *dev = &pdev->dev;
+	int ret;
+	int irq_num = 0;
+
+	mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
+	if (!mtk_dp)
+		return -ENOMEM;
+
+	mtk_dp->dev = dev;
+
+	irq_num = platform_get_irq(pdev, 0);
+	if (irq_num < 0)
+		return dev_err_probe(dev, irq_num, "failed to request dp irq resource\n");
+
+	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+	if (IS_ERR(mtk_dp->next_bridge)) {
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
+	}
+
+	ret = mtk_dp_dt_parse(mtk_dp, pdev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to parse dt\n");
+
+	drm_dp_aux_init(&mtk_dp->aux);
+	mtk_dp->aux.name = "aux_mtk_dp";
+	mtk_dp->aux.transfer = mtk_dp_aux_transfer;
+
+	ret = devm_request_threaded_irq(dev, irq_num, mtk_dp_hpd_event,
+					mtk_dp_hpd_event_thread,
+					IRQ_TYPE_LEVEL_HIGH, dev_name(dev),
+					mtk_dp);
+	if (ret)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
+
+	mutex_init(&mtk_dp->dp_lock);
+
+	platform_set_drvdata(pdev, mtk_dp);
+
+	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
+							PLATFORM_DEVID_AUTO,
+							&mtk_dp->regs,
+							sizeof(struct regmap *));
+	if (IS_ERR(mtk_dp->phy_dev))
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev), "Failed to create device mediatek-dp-phy\n");
+
+	mtk_dp_get_calibration_data(mtk_dp);
+
+	mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
+
+	if (IS_ERR(mtk_dp->phy)) {
+		platform_device_unregister(mtk_dp->phy_dev);
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n");
+	}
+
+	mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
+	mtk_dp->bridge.of_node = dev->of_node;
+
+	mtk_dp->bridge.ops =
+		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
+	drm_bridge_add(&mtk_dp->bridge);
+	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_remove(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp = platform_get_drvdata(pdev);
+
+	platform_device_unregister(mtk_dp->phy_dev);
+	mtk_dp_video_mute(mtk_dp, true);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_dp_suspend(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
+		/* Ensure the sink is off before shutting down power */
+		usleep_range(2000, 3000);
+	}
+
+	ret = mtk_dp_power_disable(mtk_dp);
+	if (ret)
+		return ret;
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+
+	mtk_dp_init_port(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+	ret = mtk_dp_power_enable(mtk_dp);
+
+	return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
+
+static const struct of_device_id mtk_dp_of_match[] = {
+	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{},
+};
+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 = &mtk_dp_pm_ops,
+	},
+};
+
+MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DisplayPort Driver");
+MODULE_LICENSE("GPL");
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 000000000000..848e5f697737
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
@@ -0,0 +1,570 @@
+/* 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                                             \
+	(BIT(0) | BIT(1) | BIT(5) | BIT(8) | BIT(10) | BIT(25) | BIT(31))
+#define MTK_DP_SIP_ATF_VIDEO_UNMUTE	BIT(5)
+#define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE (BIT(0) | BIT(5))
+
+#define DP_PHY_GLB_BIAS_GEN_00	  0
+#define RG_XTP_GLB_BIAS_INTR_CTRL GENMASK(20, 16)
+
+#define DP_PHY_GLB_DPAUX_TX    BIT(3)
+#define RG_CKM_PT0_CKTX_IMPSEL GENMASK(23, 20)
+
+#define DP_PHY_LANE_TX_0	  (BIT(2) | BIT(8))
+#define RG_XTP_LN0_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN0_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_1	  (BIT(2) | BIT(9))
+#define RG_XTP_LN1_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN1_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_2	  (BIT(2) | BIT(8) | BIT(9))
+#define RG_XTP_LN2_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN2_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_3	  (BIT(2) | BIT(10))
+#define RG_XTP_LN3_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN3_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define TOP_OFFSET   BIT(13)
+#define ENC0_OFFSET  GENMASK(13, 12)
+#define ENC1_OFFSET  (BIT(9) | BIT(12) | BIT(13))
+#define TRANS_OFFSET (BIT(10) | BIT(12) | BIT(13))
+#define AUX_OFFSET   (BIT(9) | BIT(10) | BIT(12) | BIT(13))
+#define SEC_OFFSET   BIT(14)
+
+#define MTK_DP_HPD_DISCONNECT BIT(1)
+#define MTK_DP_HPD_CONNECT    BIT(2)
+#define MTK_DP_HPD_INTERRUPT  BIT(3)
+
+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
+#define DA_XTP_GLB_CKDET_EN_FORCE_VAL BIT(15)
+#define DA_XTP_GLB_CKDET_EN_FORCE_EN  BIT(14)
+#define DA_CKM_INTCKTX_EN_FORCE_VAL   BIT(13)
+#define DA_CKM_INTCKTX_EN_FORCE_EN    BIT(12)
+#define DA_CKM_CKTX0_EN_FORCE_VAL     BIT(11)
+#define DA_CKM_CKTX0_EN_FORCE_EN      BIT(10)
+#define DA_CKM_XTAL_CK_FORCE_VAL      BIT(9)
+#define DA_CKM_XTAL_CK_FORCE_EN	      BIT(8)
+#define DA_CKM_BIAS_LPF_EN_FORCE_VAL  BIT(7)
+#define DA_CKM_BIAS_LPF_EN_FORCE_EN   BIT(6)
+#define DA_CKM_BIAS_EN_FORCE_VAL      BIT(5)
+#define DA_CKM_BIAS_EN_FORCE_EN	      BIT(4)
+#define DA_XTP_GLB_AVD10_ON_FORCE_VAL BIT(3)
+#define DA_XTP_GLB_AVD10_ON_FORCE     BIT(2)
+#define DA_XTP_GLB_LDO_EN_FORCE_VAL   BIT(1)
+#define DA_XTP_GLB_LDO_EN_FORCE_EN    BIT(0)
+
+#define MTK_DP_1040		      (BIT(6) | BIT(12))
+#define RG_DPAUX_RX_VALID_DEGLITCH_EN BIT(2)
+#define RG_XTP_GLB_CKDET_EN	      BIT(1)
+#define RG_DPAUX_RX_EN		      BIT(0)
+
+#define MTK_DP_ENC0_P0_3000		   (ENC0_OFFSET + 0x00)
+#define LANE_NUM_DP_ENC0_P0_MASK	   GENMASK(1, 0)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_MASK	   BIT(2)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT	   BIT(1)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_MASK	   BIT(3)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT	   GENMASK(1, 0)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_MASK  BIT(4)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT BIT(2)
+
+#define MTK_DP_ENC0_P0_3004			   (ENC0_OFFSET + 0x04)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK	   BIT(8)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_SHIFT	   BIT(3)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK  BIT(9)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT (BIT(0) | BIT(3))
+
+#define MTK_DP_ENC0_P0_3008		  (ENC0_OFFSET + 0x08)
+#define VIDEO_M_CODE_SW_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_300C		  (ENC0_OFFSET + 0x0C)
+#define VIDEO_M_CODE_SW_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3010	  (ENC0_OFFSET + 0x10)
+#define HTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3014	  (ENC0_OFFSET + 0x14)
+#define VTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3018	  (ENC0_OFFSET + 0x18)
+#define HSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_301C	  (ENC0_OFFSET + 0x1C)
+#define VSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3020	  (ENC0_OFFSET + 0x20)
+#define HWIDTH_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3024	   (ENC0_OFFSET + 0x24)
+#define VHEIGHT_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3028	(ENC0_OFFSET + 0x28)
+#define HSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define HSW_SW_DP_ENC0_P0_SHIFT 0
+#define HSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_302C	(ENC0_OFFSET + 0x2C)
+#define VSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define VSW_SW_DP_ENC0_P0_SHIFT 0
+#define VSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_3030			 (ENC0_OFFSET + 0x30)
+#define HTOTAL_SEL_DP_ENC0_P0_SHIFT		 0
+#define VTOTAL_SEL_DP_ENC0_P0_SHIFT		 BIT(0)
+#define HSTART_SEL_DP_ENC0_P0_SHIFT		 BIT(1)
+#define VSTART_SEL_DP_ENC0_P0_SHIFT		 GENMASK(1, 0)
+#define HWIDTH_SEL_DP_ENC0_P0_SHIFT		 BIT(2)
+#define VHEIGHT_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(2))
+#define HSP_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 1)
+#define HSW_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 0)
+#define VSP_SEL_DP_ENC0_P0_SHIFT		 BIT(3)
+#define VSW_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK	 (BIT(11))
+#define VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT	 (BIT(0) | BIT(1) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK (BIT(12))
+#define VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT	 GENMASK(3, 2)
+
+#define MTK_DP_ENC0_P0_3034 (ENC0_OFFSET + 0x34)
+
+#define MTK_DP_ENC0_P0_3038		  (ENC0_OFFSET + 0x38)
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK  (BIT(11))
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_SHIFT (BIT(0) | BIT(1) | BIT(3))
+
+#define MTK_DP_ENC0_P0_303C		      (ENC0_OFFSET + 0x3C)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT 0
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK     GENMASK(10, 8)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT    BIT(3)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT                                     \
+	(0 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT                                     \
+	(1 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT                                     \
+	(2 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT                                      \
+	(3 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT                                      \
+	(4 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK  GENMASK(14, 12)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT GENMASK(3, 2)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB                                     \
+	(0 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422                                \
+	(1 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420                                \
+	(2 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK	 (BIT(15))
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT GENMASK(3, 0)
+
+#define MTK_DP_ENC0_P0_3040		   (ENC0_OFFSET + 0x40)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_3044	       (ENC0_OFFSET + 0x44)
+#define VIDEO_N_CODE_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3048	       (ENC0_OFFSET + 0x48)
+#define VIDEO_N_CODE_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_304C		      (ENC0_OFFSET + 0x4C)
+#define VBID_VIDEO_MUTE_DP_ENC0_P0_MASK	      BIT(2)
+#define SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK BIT(8)
+
+#define MTK_DP_ENC0_P0_3050		      (ENC0_OFFSET + 0x50)
+#define VIDEO_N_CODE_MN_GEN_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3054		      (ENC0_OFFSET + 0x54)
+#define VIDEO_N_CODE_MN_GEN_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3064	     (ENC0_OFFSET + 0x64)
+#define HDE_NUM_LAST_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3088	      (ENC0_OFFSET + 0x88)
+#define AU_EN_DP_ENC0_P0_MASK	      BIT(6)
+#define AU_EN_DP_ENC0_P0_SHIFT	      GENMASK(2, 1)
+#define AUDIO_8CH_EN_DP_ENC0_P0_MASK  BIT(7)
+#define AUDIO_8CH_SEL_DP_ENC0_P0_MASK BIT(8)
+#define AUDIO_2CH_EN_DP_ENC0_P0_MASK  (BIT(14))
+#define AUDIO_2CH_SEL_DP_ENC0_P0_MASK (BIT(15))
+
+#define MTK_DP_ENC0_P0_308C	    (ENC0_OFFSET + 0x8C)
+#define CH_STATUS_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3090	    (ENC0_OFFSET + 0x90)
+#define CH_STATUS_1_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3094	    (ENC0_OFFSET + 0x94)
+#define CH_STATUS_2_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A0 (ENC0_OFFSET + 0xA0)
+
+#define MTK_DP_ENC0_P0_30A4	  (ENC0_OFFSET + 0xA4)
+#define AU_TS_CFG_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A8 (ENC0_OFFSET + 0xA8)
+
+#define MTK_DP_ENC0_P0_30AC (ENC0_OFFSET + 0xAC)
+
+#define MTK_DP_ENC0_P0_30B0 (ENC0_OFFSET + 0xB0)
+
+#define MTK_DP_ENC0_P0_30B4	  (ENC0_OFFSET + 0xB4)
+#define ISRC_CFG_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define ISRC_CFG_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_30B8 (ENC0_OFFSET + 0xB8)
+
+#define MTK_DP_ENC0_P0_30BC			   (ENC0_OFFSET + 0xBC)
+#define ISRC_CONT_DP_ENC0_P0_MASK		   BIT(0)
+#define ISRC_CONT_DP_ENC0_P0_SHIFT		   0
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK  GENMASK(10, 8)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT BIT(3)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_2                             \
+	(1 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_4                             \
+	(2 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_8                             \
+	(3 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2                             \
+	(5 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_4                             \
+	(6 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_8                             \
+	(7 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+
+#define MTK_DP_ENC0_P0_30D8 (ENC0_OFFSET + 0xD8)
+
+#define MTK_DP_ENC0_P0_312C	 (ENC0_OFFSET + 0x12C)
+#define ASP_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define ASP_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define ASP_HB3_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_3130 (ENC0_OFFSET + 0x130)
+
+#define MTK_DP_ENC0_P0_3138 (ENC0_OFFSET + 0x138)
+
+#define MTK_DP_ENC0_P0_3154	    (ENC0_OFFSET + 0x154)
+#define PGEN_HTOTAL_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3158		  (ENC0_OFFSET + 0x158)
+#define PGEN_HSYNC_RISING_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_315C		       (ENC0_OFFSET + 0x15C)
+#define PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3160		(ENC0_OFFSET + 0x160)
+#define PGEN_HFDE_START_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3164		       (ENC0_OFFSET + 0x164)
+#define PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3168	    (ENC0_OFFSET + 0x168)
+#define PGEN_VTOTAL_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_316C		  (ENC0_OFFSET + 0x16C)
+#define PGEN_VSYNC_RISING_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3170		       (ENC0_OFFSET + 0x170)
+#define PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3174		(ENC0_OFFSET + 0x174)
+#define PGEN_VFDE_START_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3178		       (ENC0_OFFSET + 0x178)
+#define PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_31B0    (ENC0_OFFSET + 0x1B0)
+#define PGEN_PATTERN_SEL_SHIFT BIT(2)
+#define PGEN_PATTERN_SEL_MASK  GENMASK(6, 4)
+
+#define MTK_DP_ENC0_P0_31C8		  (ENC0_OFFSET + 0x1C8)
+#define VSC_EXT_VESA_HB0_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31CC		  (ENC0_OFFSET + 0x1CC)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_VESA_HB3_DP_ENC0_P0_MASK  GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D0		 (ENC0_OFFSET + 0x1D0)
+#define VSC_EXT_CEA_HB0_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31D4		 (ENC0_OFFSET + 0x1D4)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D8		  (ENC0_OFFSET + 0x1D8)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_MASK	  GENMASK(13, 8)
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_SHIFT  BIT(3)
+
+#define MTK_DP_ENC0_P0_31DC	  (ENC0_OFFSET + 0x1DC)
+#define HDR0_CFG_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define HDR0_CFG_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_31E8 (ENC0_OFFSET + 0x1E8)
+
+#define MTK_DP_ENC0_P0_31EC		  (ENC0_OFFSET + 0x1EC)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK  BIT(4)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT BIT(2)
+#define ISRC1_HB3_DP_ENC0_P0_MASK	  GENMASK(15, 8)
+#define ISRC1_HB3_DP_ENC0_P0_SHIFT	  BIT(3)
+
+#define MTK_DP_ENC1_P0_3200 (ENC1_OFFSET + 0x00)
+
+#define MTK_DP_ENC1_P0_3280		(ENC1_OFFSET + 0x80)
+#define SDP_PACKET_TYPE_DP_ENC1_P0_MASK GENMASK(4, 0)
+#define SDP_PACKET_W_DP_ENC1_P0		BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_MASK	BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_SHIFT	(BIT(0) | BIT(2))
+
+#define MTK_DP_ENC1_P0_328C (ENC1_OFFSET + 0x8C)
+
+#define MTK_DP_ENC1_P0_3290 (ENC1_OFFSET + 0x90)
+
+#define MTK_DP_ENC1_P0_32A0 (ENC1_OFFSET + 0xA0)
+
+#define MTK_DP_ENC1_P0_32A4 (ENC1_OFFSET + 0xA4)
+
+#define MTK_DP_ENC1_P0_3300		     (ENC1_OFFSET + 0x100)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC1_P0_3304			  (ENC1_OFFSET + 0x104)
+#define AU_PRTY_REGEN_DP_ENC1_P0_MASK		  BIT(8)
+#define AU_CH_STS_REGEN_DP_ENC1_P0_MASK		  BIT(9)
+#define AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK (BIT(12))
+
+#define MTK_DP_ENC1_P0_3324		  (ENC1_OFFSET + 0x124)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT BIT(3)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX                                       \
+	(0 << AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT)
+
+#define MTK_DP_ENC1_P0_3364			     (ENC1_OFFSET + 0x164)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT 0
+#define FIFO_READ_START_POINT_DP_ENC1_P0_MASK	     GENMASK(15, 12)
+#define FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT	     GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_3368			       (ENC1_OFFSET + 0x168)
+#define VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT 0
+#define VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT	       BIT(2)
+#define SDP_DP13_EN_DP_ENC1_P0_SHIFT		       BIT(3)
+#define BS2BS_MODE_DP_ENC1_P0_MASK		       GENMASK(13, 12)
+#define BS2BS_MODE_DP_ENC1_P0_SHIFT		       GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_33F4 (ENC1_OFFSET + 0x1F4)
+
+#define MTK_DP_TRANS_P0_3400	      (TRANS_OFFSET + 0)
+#define PATTERN1_EN_DP_TRANS_P0_MASK  BIT(12)
+#define PATTERN1_EN_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+#define PATTERN2_EN_DP_TRANS_P0_MASK  BIT(13)
+#define PATTERN3_EN_DP_TRANS_P0_MASK  BIT(14)
+#define PATTERN4_EN_DP_TRANS_P0_MASK  BIT(15)
+
+#define MTK_DP_TRANS_P0_3404	   (TRANS_OFFSET + 0x4)
+#define DP_SCR_EN_DP_TRANS_P0_MASK BIT(0)
+
+#define MTK_DP_TRANS_P0_340C			       (TRANS_OFFSET + 0xC)
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK (BIT(13))
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT                        \
+	(BIT(0) | BIT(2) | BIT(3))
+
+#define MTK_DP_TRANS_P0_3410		    (TRANS_OFFSET + 0x10)
+#define HPD_DEB_THD_DP_TRANS_P0_MASK	    GENMASK(3, 0)
+#define HPD_DEB_THD_DP_TRANS_P0_SHIFT	    0
+#define HPD_INT_THD_DP_TRANS_P0_MASK	    GENMASK(7, 4)
+#define HPD_INT_THD_DP_TRANS_P0_SHIFT	    BIT(2)
+#define HPD_INT_THD_DP_TRANS_P0_LOWER_500US (2 << HPD_INT_THD_DP_TRANS_P0_SHIFT)
+#define HPD_INT_THD_DP_TRANS_P0_UPPER_1100US                                   \
+	(2 << (HPD_INT_THD_DP_TRANS_P0_SHIFT + 2))
+#define HPD_DISC_THD_DP_TRANS_P0_MASK  GENMASK(11, 8)
+#define HPD_DISC_THD_DP_TRANS_P0_SHIFT BIT(3)
+#define HPD_CONN_THD_DP_TRANS_P0_MASK  GENMASK(15, 12)
+#define HPD_CONN_THD_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_3414	(TRANS_OFFSET + 0x14)
+#define HPD_DB_DP_TRANS_P0_MASK BIT(2)
+
+#define MTK_DP_TRANS_P0_3418	      (TRANS_OFFSET + 0x18)
+#define IRQ_CLR_DP_TRANS_P0_MASK      GENMASK(3, 0)
+#define IRQ_MASK_DP_TRANS_P0_MASK     GENMASK(7, 4)
+#define IRQ_MASK_DP_TRANS_P0_SHIFT    BIT(2)
+#define IRQ_MASK_DP_TRANS_P0_DISC_IRQ (BIT(1) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_CONN_IRQ (BIT(2) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_INT_IRQ  (BIT(3) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_STATUS_DP_TRANS_P0_MASK   GENMASK(15, 12)
+#define IRQ_STATUS_DP_TRANS_P0_SHIFT  GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_342C	      (TRANS_OFFSET + 0x2C)
+#define XTAL_FREQ_DP_TRANS_P0_DEFAULT (BIT(0) | BIT(3) | BIT(5) | BIT(6))
+#define XTAL_FREQ_DP_TRANS_P0_MASK    GENMASK(7, 0)
+
+#define MTK_DP_TRANS_P0_3430			   (TRANS_OFFSET + 0x30)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_MASK	   GENMASK(1, 0)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT BIT(1)
+
+#define MTK_DP_TRANS_P0_34A4	   (TRANS_OFFSET + 0xA4)
+#define LANE_NUM_DP_TRANS_P0_MASK  GENMASK(3, 2)
+#define LANE_NUM_DP_TRANS_P0_SHIFT BIT(1)
+
+#define MTK_DP_TRANS_P0_3540		    (TRANS_OFFSET + 0x140)
+#define FEC_EN_DP_TRANS_P0_MASK		    BIT(0)
+#define FEC_EN_DP_TRANS_P0_SHIFT	    0
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK  BIT(3)
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_TRANS_P0_3580			 (TRANS_OFFSET + 0x180)
+#define POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK BIT(8)
+#define POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK BIT(9)
+#define POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK (BIT(10))
+#define POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK (BIT(11))
+
+#define MTK_DP_TRANS_P0_35C4	     (TRANS_OFFSET + 0x1C4)
+#define SW_IRQ_MASK_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35C8	    (TRANS_OFFSET + 0x1C8)
+#define SW_IRQ_CLR_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define SW_IRQ_STATUS_DP_TRANS_P0_MASK	GENMASK(15, 0)
+#define SW_IRQ_STATUS_DP_TRANS_P0_SHIFT 0
+
+#define MTK_DP_TRANS_P0_35D0		     (TRANS_OFFSET + 0x1D0)
+#define SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35F0 (TRANS_OFFSET + 0x1F0)
+
+#define MTK_DP_AUX_P0_360C	       (AUX_OFFSET + 0xC)
+#define AUX_TIMEOUT_THR_AUX_TX_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_AUX_P0_3614		  (AUX_OFFSET + 0x14)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK  GENMASK(6, 0)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3618			 (AUX_OFFSET + 0x18)
+#define AUX_RX_FIFO_FULL_AUX_TX_P0_MASK		 BIT(9)
+#define AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3620		      (AUX_OFFSET + 0x20)
+#define AUX_RD_MODE_AUX_TX_P0_MASK	      BIT(9)
+#define AUX_RX_FIFO_READ_PULSE_TX_P0_MASK     BIT(8)
+#define AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT	      BIT(3)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK  GENMASK(7, 0)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3624		    (AUX_OFFSET + 0x24)
+#define AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3628		 (AUX_OFFSET + 0x28)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_MASK	 GENMASK(9, 0)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT 0
+#define AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE                                     \
+	(BIT(0) << AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT)
+
+#define MTK_DP_AUX_P0_362C		  (AUX_OFFSET + 0x2C)
+#define AUX_NO_LENGTH_AUX_TX_P0_MASK	  BIT(0)
+#define AUX_NO_LENGTH_AUX_TX_P0_SHIFT	  0
+#define AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK BIT(1)
+#define AUX_RESERVED_RW_0_AUX_TX_P0_MASK  GENMASK(15, 2)
+
+#define MTK_DP_AUX_P0_3630		     (AUX_OFFSET + 0x30)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_MASK  BIT(3)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_AUX_P0_3634			(AUX_OFFSET + 0x34)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK	GENMASK(15, 8)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3640			      (AUX_OFFSET + 0x40)
+#define AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK	      BIT(6)
+#define AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT  GENMASK(2, 1)
+#define AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT (BIT(0) | BIT(2))
+#define AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT BIT(2)
+#define AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT	      GENMASK(1, 0)
+#define AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(1)
+#define AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT	      0
+
+#define MTK_DP_AUX_P0_3644		   (AUX_OFFSET + 0x44)
+#define MCU_REQUEST_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3648		       (AUX_OFFSET + 0x48)
+#define MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_AUX_P0_364C		       (AUX_OFFSET + 0x4C)
+#define MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3650		      (AUX_OFFSET + 0x50)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_MASK	      GENMASK(15, 12)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT      GENMASK(3, 2)
+#define PHY_FIFO_RST_AUX_TX_P0_MASK	      BIT(9)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK  BIT(8)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3658	    (AUX_OFFSET + 0x58)
+#define AUX_TX_OV_EN_AUX_TX_P0_MASK BIT(0)
+
+#define MTK_DP_AUX_P0_3690		       (AUX_OFFSET + 0x90)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK  BIT(8)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3704				      (AUX_OFFSET + 0x104)
+#define AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK BIT(1)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK		      BIT(2)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT		      BIT(1)
+
+#define MTK_DP_AUX_P0_3708 (AUX_OFFSET + 0x108)
+
+#define MTK_DP_AUX_P0_37C8	    (AUX_OFFSET + 0x1C8)
+#define MTK_ATOP_EN_AUX_TX_P0_MASK  BIT(0)
+#define MTK_ATOP_EN_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_TOP_PWR_STATE	       (TOP_OFFSET + 0x0)
+#define DP_PWR_STATE_MASK	       GENMASK(1, 0)
+#define DP_PWR_STATE_BANDGAP	       BIT(0)
+#define DP_PWR_STATE_BANDGAP_TPLL      BIT(1)
+#define DP_PWR_STATE_BANDGAP_TPLL_LANE GENMASK(1, 0)
+
+#define MTK_DP_TOP_SWING_EMP	(TOP_OFFSET + 0x4)
+#define DP_TX0_VOLT_SWING_MASK	GENMASK(1, 0)
+#define DP_TX0_VOLT_SWING_SHIFT 0
+#define DP_TX0_PRE_EMPH_MASK	GENMASK(3, 2)
+#define DP_TX0_PRE_EMPH_SHIFT	BIT(1)
+#define DP_TX1_VOLT_SWING_MASK	GENMASK(9, 8)
+#define DP_TX1_VOLT_SWING_SHIFT BIT(3)
+#define DP_TX1_PRE_EMPH_MASK	GENMASK(11, 10)
+#define DP_TX2_VOLT_SWING_MASK	GENMASK(17, 16)
+#define DP_TX2_PRE_EMPH_MASK	GENMASK(19, 18)
+#define DP_TX3_VOLT_SWING_MASK	GENMASK(25, 24)
+#define DP_TX3_PRE_EMPH_MASK	GENMASK(27, 26)
+
+#define MTK_DP_TOP_RESET_AND_PROBE (TOP_OFFSET + 0x20)
+#define SW_RST_B_SHIFT		   0
+#define SW_RST_B_PHYD		   (BIT(4) << SW_RST_B_SHIFT)
+
+#define MTK_DP_TOP_IRQ_STATUS	   (TOP_OFFSET + 0x28)
+#define RGS_IRQ_STATUS_SHIFT	   0
+#define RGS_IRQ_STATUS_TRANSMITTER (BIT(1) << RGS_IRQ_STATUS_SHIFT)
+
+#define MTK_DP_TOP_IRQ_MASK  (TOP_OFFSET + 0x2C)
+#define IRQ_MASK_AUX_TOP_IRQ BIT(2)
+
+#define MTK_DP_TOP_MEM_PD (TOP_OFFSET + 0x38)
+#define MEM_ISO_EN_SHIFT  0
+#define FUSE_SEL_SHIFT	  BIT(1)
+
+#endif /*_MTK_DP_REG_H_*/
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index e25ac61aac08..4e378eb34071 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -906,6 +906,9 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+	&mtk_dp_driver,
+#endif
 	&mtk_drm_platform_driver,
 	&mtk_dsi_driver,
 	&mtk_ethdr_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 8d3ff32b5364..04de9436ea85 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -59,6 +59,9 @@ extern struct platform_driver mtk_disp_ovl_adaptor_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+extern struct platform_driver mtk_dp_driver;
+#endif
 extern struct platform_driver mtk_dsi_driver;
 extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.

It supports the mt8195, the embedded DisplayPort units. It offers
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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/Kconfig       |    8 +
 drivers/gpu/drm/mediatek/Makefile      |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2570 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  570 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |    3 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |    3 +
 6 files changed, 3156 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..a37b6ec9f01e 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -21,6 +21,14 @@ config DRM_MEDIATEK
 	  This driver provides kernel mode setting and
 	  buffer management to userspace.
 
+config DRM_MEDIATEK_DP
+	tristate "DRM DPTX Support for Mediatek SoCs"
+	depends on DRM_MEDIATEK
+	select PHY_MTK_DP
+	select DRM_DP_HELPER
+	help
+	  DRM/KMS Display Port driver for Mediatek SoCs.
+
 config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 3abd27d7c91d..d4d193f60271 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_DRM_MEDIATEK_DP) += 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 000000000000..8eb17ae82bfd
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +-2,2567 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/dp/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/hdmi-codec.h>
+#include <video/videomode.h>
+
+#include "mtk_dp_reg.h"
+
+#define MTK_VDOSYS1_MAX_FRAMERATE 60
+#define MTK_DP_4P1T 4
+#define MTK_DP_HDE 2
+#define MTK_DP_PIX_PER_ADDR 2
+#define MTK_DP_AUX_WAIT_REPLY_COUNT 20
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT 3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT 8
+#define MTK_DP_TRAIN_MAX_ITERATIONS 5
+
+#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_NORMAL,
+	MTK_DP_TRAIN_STATE_DPIDLE,
+};
+
+struct mtk_dp_timings {
+	struct videomode vm;
+
+	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;
+
+	u8  irq_status;
+	int check_cap_count;
+};
+
+/* 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,
+};
+
+//TODO: redundant with DP_MSA_MISC_*_BPC ?
+/* Same values as used for DP Spec MISC0 bits 5,6,7 */
+enum mtk_dp_color_depth {
+	MTK_DP_COLOR_DEPTH_6BIT = 0,
+	MTK_DP_COLOR_DEPTH_8BIT = 1,
+	MTK_DP_COLOR_DEPTH_10BIT = 2,
+	MTK_DP_COLOR_DEPTH_12BIT = 3,
+	MTK_DP_COLOR_DEPTH_16BIT = 4,
+	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
+};
+
+struct mtk_dp_info {
+	enum mtk_dp_color_depth depth;
+	enum dp_pixelformat format;
+	struct mtk_dp_timings timings;
+};
+
+struct dp_cal_data {
+	unsigned int glb_bias_trim;
+	unsigned int clktx_impse;
+
+	unsigned int *ln_tx_impsel_pmos;
+	unsigned int *ln_tx_impsel_nmos;
+};
+
+struct mtk_dp {
+	struct device *dev;
+	struct platform_device *phy_dev;
+	struct phy *phy;
+	struct dp_cal_data cal_data;
+	u8 max_lanes;
+	u8 max_linkrate;
+
+	struct drm_device *drm_dev;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_dp_aux aux;
+
+	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
+
+	struct mtk_dp_info info;
+	enum mtk_dp_state state;
+
+	struct mtk_dp_train_info train_info;
+	enum mtk_dp_train_state train_state;
+	unsigned int input_fmt;
+
+	struct regmap *regs;
+	struct clk *dp_tx_clk;
+
+	bool enabled;
+
+	bool has_fec;
+	/* Protects the mtk_dp struct */
+	struct mutex dp_lock;
+
+	struct drm_connector *conn;
+};
+
+static struct regmap_config mtk_dp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = SEC_OFFSET + 0x90,
+	.name = "mtk-dp-registers",
+};
+
+static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
+{
+	return container_of(b, struct mtk_dp, bridge);
+}
+
+static u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
+{
+	u32 read_val;
+	int ret;
+
+	ret = regmap_read(mtk_dp->regs, offset, &read_val);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to read register 0x%x: %d\n",
+			offset, ret);
+		return 0;
+	}
+
+	return read_val;
+}
+
+static int mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
+{
+	int ret;
+
+	ret = regmap_write(mtk_dp->regs, offset, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to write register 0x%x with value 0x%x: %d\n",
+			offset, val, ret);
+	return ret;
+}
+
+static int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset, u32 val,
+			      u32 mask)
+{
+	int ret;
+
+	ret = regmap_update_bits(mtk_dp->regs, offset, mask, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to update register 0x%x with value 0x%x, mask 0x%x: %d\n",
+			offset, val, mask, ret);
+	return ret;
+}
+
+static int mtk_dp_bulk_16bit_write(struct mtk_dp *mtk_dp, u32 offset, u8 *buf,
+				   size_t length)
+{
+	int i;
+	int ret = 0;
+	int num_regs = (length + 1) / 2;
+
+	/* 2 bytes per register */
+	for (i = 0; i < num_regs; i++) {
+		u32 val = buf[i * 2] |
+			  (i * 2 + 1 < length ? buf[i * 2 + 1] << 8 : 0);
+
+		ret = mtk_dp_write(mtk_dp, offset + i * 4, val);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static unsigned long mtk_dp_sip_atf_call(unsigned int cmd, unsigned int para)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32, cmd, para, 0, 0, 0, 0, 0,
+		      &res);
+
+	pr_debug("[DPTX]%s cmd 0x%x, p1 0x%x, ret 0x%lx-0x%lx", __func__, cmd,
+		 para, res.a0, res.a1);
+	return res.a1;
+}
+
+static int mtk_dp_msa_bypass_disable(struct mtk_dp *mtk_dp)
+{
+	const u16 bits_to_set =
+		BIT(HTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HWIDTH_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VHEIGHT_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSP_SEL_DP_ENC0_P0_SHIFT) | BIT(HSW_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSP_SEL_DP_ENC0_P0_SHIFT) | BIT(VSW_SEL_DP_ENC0_P0_SHIFT);
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3030, bits_to_set,
+			   bits_to_set);
+}
+
+static int mtk_dp_set_msa(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3010, mode.htotal,
+				 HTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3018,
+				 timings->vm.hsync_len + timings->vm.hback_porch,
+			   HSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028,
+				 timings->vm.hsync_len << HSW_SW_DP_ENC0_P0_SHIFT,
+			   HSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028, 0,
+				 HSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3020, timings->vm.hactive,
+				 HWIDTH_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3014, mode.vtotal,
+				 VTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_301C,
+				 timings->vm.vsync_len + timings->vm.vback_porch,
+			   VSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C,
+				 timings->vm.vsync_len << VSW_SW_DP_ENC0_P0_SHIFT,
+			   VSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C, 0,
+				 VSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3024, timings->vm.vactive,
+				 VHEIGHT_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3064, timings->vm.hactive,
+				 HDE_NUM_LAST_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3154, mode.htotal,
+				 PGEN_HTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3158,
+				 timings->vm.hfront_porch,
+			   PGEN_HSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_315C, timings->vm.hsync_len,
+				 PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
+				 timings->vm.hback_porch + timings->vm.hsync_len,
+			   PGEN_HFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3164, timings->vm.hactive,
+				 PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3168, mode.vtotal,
+				 PGEN_VTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_316C,
+				 timings->vm.vfront_porch,
+			   PGEN_VSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3170, timings->vm.vsync_len,
+				 PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
+				 timings->vm.vback_porch + timings->vm.vsync_len,
+			   PGEN_VFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3178, timings->vm.vactive,
+				 PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
+				   enum dp_pixelformat color_format)
+{
+	u32 val;
+	int ret;
+
+	mtk_dp->info.format = color_format;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_format << DP_TEST_COLOR_FORMAT_SHIFT,
+				 DP_TEST_COLOR_FORMAT_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_format) {
+	case DP_PIXELFORMAT_YUV422:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422;
+		break;
+	case DP_PIXELFORMAT_YUV420:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420;
+		break;
+	case DP_PIXELFORMAT_RGB:
+	case DP_PIXELFORMAT_YUV444:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
+		break;
+	case DP_PIXELFORMAT_Y_ONLY:
+	case DP_PIXELFORMAT_RAW:
+	case DP_PIXELFORMAT_RESERVED:
+	default:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
+			 color_format);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_color_depth(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_color_depth color_depth)
+{
+	int ret;
+	u32 val;
+
+	mtk_dp->info.depth = color_depth;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_depth << DP_TEST_BIT_DEPTH_SHIFT,
+				 DP_TEST_BIT_DEPTH_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_depth) {
+	case MTK_DP_COLOR_DEPTH_6BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_8BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_10BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_12BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_16BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_UNKNOWN:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color depth %d\n",
+			 color_depth);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_mn_overwrite_disable(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				  VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_sram_read_start(struct mtk_dp *mtk_dp, u32 val)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				  val << SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT,
+				  SRAM_START_READ_THRD_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_setup_encoder(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				 BIT(VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT),
+				 VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+				 0x20 << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 0x20 << SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3300,
+				 2 << VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT,
+			    VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 4 << FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT,
+			    FIFO_READ_START_POINT_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368,
+			   1 << VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT |
+			   1 << VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT |
+			   BIT(SDP_DP13_EN_DP_ENC1_P0_SHIFT) |
+			   1 << BS2BS_MODE_DP_ENC1_P0_SHIFT);
+
+	return ret;
+}
+
+static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3038, 0,
+				 VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31B0,
+				 4 << PGEN_PATTERN_SEL_SHIFT, PGEN_PATTERN_SEL_MASK);
+
+	return ret;
+}
+
+static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
+{
+	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
+		  HPD_DB_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT));
+	/* Wait for the irq to be cleared */
+	usleep_range(MTK_DP_AUX_WRITE_READ_WAIT_TIME_US,
+		     MTK_DP_AUX_WRITE_READ_WAIT_TIME_US * 2);
+}
+
+static int mtk_dp_aux_set_cmd(struct mtk_dp *mtk_dp, u8 cmd, u32 addr)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3644, cmd,
+				 MCU_REQUEST_COMMAND_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3648, addr,
+				 MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_364C, addr >> 16,
+				 MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_aux_cmd_complete(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+				  BIT(MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT),
+				  MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK |
+				  PHY_FIFO_RST_AUX_TX_P0_MASK |
+				  MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+}
+
+static int mtk_dp_aux_request_ready(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3630,
+				  BIT(AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT),
+				  AUX_TX_REQUEST_READY_AUX_TX_P0_MASK);
+}
+
+static void mtk_dp_aux_fill_write_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				       size_t length)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_AUX_P0_3708, buf, length);
+}
+
+static int mtk_dp_aux_read_rx_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				   size_t length, int read_delay)
+{
+	int ret;
+	int read_pos;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620, 0,
+				 AUX_RD_MODE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+
+	for (read_pos = 0; read_pos < length; read_pos++) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620,
+					 BIT(AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT),
+					 AUX_RX_FIFO_READ_PULSE_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Hardware needs time to update the data */
+		usleep_range(read_delay, read_delay * 2);
+		buf[read_pos] =
+			(u8)(mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3620) &
+			     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK >>
+				     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_set_length(struct mtk_dp *mtk_dp, size_t length)
+{
+	int ret;
+
+	if (length > 0) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+					 (length - 1)
+					 << MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT,
+					 MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C,
+					 BIT(AUX_NO_LENGTH_AUX_TX_P0_SHIFT),
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_wait_for_completion(struct mtk_dp *mtk_dp, bool is_read)
+{
+	int wait_reply = MTK_DP_AUX_WAIT_REPLY_COUNT;
+
+	while (--wait_reply) {
+		u32 aux_irq_status;
+
+		if (is_read) {
+			u32 fifo_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3618);
+
+			if (fifo_status &
+			    (AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK |
+			     AUX_RX_FIFO_FULL_AUX_TX_P0_MASK)) {
+				return 0;
+			}
+		}
+
+		aux_irq_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3640);
+		if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK)
+			return 0;
+
+		if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK)
+			return -ETIMEDOUT;
+
+		/* Give the hardware a chance to reach completion before retrying */
+		usleep_range(100, 500);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
+				  u32 addr, u8 *buf, size_t length)
+{
+	int ret;
+	u32 reply_cmd;
+
+	if (is_read && (length > DP_AUX_MAX_PAYLOAD_BYTES ||
+			(cmd == DP_AUX_NATIVE_READ && !length)))
+		return -EINVAL;
+
+	if (!is_read) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 BIT(AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT),
+					 AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	mtk_dp_aux_set_cmd(mtk_dp, cmd, addr);
+	mtk_dp_aux_set_length(mtk_dp, length);
+
+	if (!is_read) {
+		if (length)
+			mtk_dp_aux_fill_write_fifo(mtk_dp, buf, length);
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_request_ready(mtk_dp);
+
+	ret = mtk_dp_aux_wait_for_completion(mtk_dp, is_read);
+
+	reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
+		    AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
+
+	if (ret || reply_cmd) {
+		u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
+				 AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
+		if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) {
+			drm_err(mtk_dp->drm_dev,
+				"AUX Rx Aux hang, need SW reset\n");
+			return -EIO;
+		}
+
+		mtk_dp_aux_cmd_complete(mtk_dp);
+		mtk_dp_aux_irq_clear(mtk_dp);
+
+		return -ETIMEDOUT;
+	}
+
+	if (!length) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+
+	} else if (is_read) {
+		int read_delay;
+
+		if (cmd == (DP_AUX_I2C_READ | DP_AUX_I2C_MOT) ||
+		    cmd == DP_AUX_I2C_READ)
+			read_delay = 500;
+		else
+			read_delay = 100;
+
+		mtk_dp_aux_read_rx_fifo(mtk_dp, buf, length, read_delay);
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	return 0;
+}
+
+static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
+					  int swing_val, int preemphasis)
+{
+	int ret;
+
+	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
+
+	if (lane_num < 0 || lane_num > 3)
+		return false;
+
+	dev_dbg(mtk_dp->dev,
+		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
+		swing_val, preemphasis);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 swing_val << (DP_TX0_VOLT_SWING_SHIFT + lane_shift),
+				 DP_TX0_VOLT_SWING_MASK << lane_shift);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT + lane_shift),
+				 DP_TX0_PRE_EMPH_MASK << lane_shift);
+
+	return !ret;
+}
+
+static int mtk_dp_reset_swing_pre_emphasis(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP, 0,
+				  DP_TX0_VOLT_SWING_MASK | DP_TX1_VOLT_SWING_MASK |
+				  DP_TX2_VOLT_SWING_MASK |
+				  DP_TX3_VOLT_SWING_MASK |
+				  DP_TX0_PRE_EMPH_MASK | DP_TX1_PRE_EMPH_MASK |
+				  DP_TX2_PRE_EMPH_MASK | DP_TX3_PRE_EMPH_MASK);
+}
+
+static int mtk_dp_fec_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				  enable ? BIT(FEC_EN_DP_TRANS_P0_SHIFT) : 0,
+				  FEC_EN_DP_TRANS_P0_MASK);
+}
+
+static u32 mtk_dp_swirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u32 irq_status = mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_35D0) &
+			 SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, irq_status,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, 0,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+	}
+
+	return irq_status;
+}
+
+static u32 mtk_dp_hwirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u8 irq_status = (mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3418) &
+			 IRQ_STATUS_DP_TRANS_P0_MASK) >>
+			IRQ_STATUS_DP_TRANS_P0_SHIFT;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, irq_status,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, 0,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+	}
+
+	return irq_status;
+}
+
+static int mtk_dp_hwirq_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = enable ? 0 : IRQ_MASK_DP_TRANS_P0_DISC_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_CONN_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_INT_IRQ;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, val,
+			   IRQ_MASK_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_342C,
+				 XTAL_FREQ_DP_TRANS_P0_DEFAULT,
+			   XTAL_FREQ_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				 BIT(FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT),
+			   FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+				 BIT(AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT),
+			   AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_IRQ_MASK, IRQ_MASK_AUX_TOP_IRQ,
+				 IRQ_MASK_AUX_TOP_IRQ);
+
+	return ret;
+}
+
+static void mtk_dp_initialize_hpd_detect_settings(struct mtk_dp *mtk_dp)
+{
+	/* Debounce threshold */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   8 << HPD_DEB_THD_DP_TRANS_P0_SHIFT,
+			   HPD_DEB_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
+			    HPD_INT_THD_DP_TRANS_P0_UPPER_1100US)
+				   << HPD_INT_THD_DP_TRANS_P0_SHIFT,
+			   HPD_INT_THD_DP_TRANS_P0_MASK);
+
+	/* Connect threshold 1.5ms + 5 x 0.1ms = 2ms
+	 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (5 << HPD_DISC_THD_DP_TRANS_P0_SHIFT) |
+				   (5 << HPD_CONN_THD_DP_TRANS_P0_SHIFT),
+			   HPD_DISC_THD_DP_TRANS_P0_MASK |
+				   HPD_CONN_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	/* modify timeout threshold = 1595 [12 : 8] */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_360C, 0x1595,
+				 AUX_TIMEOUT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3658, 0,
+				 AUX_TX_OV_EN_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 25 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3634,
+				 25 << AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT,
+			   AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 13 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3614,
+				 13 << AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT,
+			   AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_37C8,
+				 BIT(MTK_ATOP_EN_AUX_TX_P0_SHIFT),
+			   MTK_ATOP_EN_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 VBID_VIDEO_MUTE_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	mtk_dp_set_color_format(mtk_dp, DP_PIXELFORMAT_RGB);
+	mtk_dp_set_color_depth(mtk_dp, MTK_DP_COLOR_DEPTH_8BIT);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3368,
+				 1 << BS2BS_MODE_DP_ENC1_P0_SHIFT,
+			   BS2BS_MODE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* dp tx encoder reset all sw */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
+				 BIT(DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT),
+			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				 DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_digital_sw_reset(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C,
+				 BIT(DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT),
+			   DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C, 0,
+				 DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_lanes(struct mtk_dp *mtk_dp, int lanes)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35F0,
+				 lanes == 0 ? 0 : BIT(3), BIT(3) | BIT(2));
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, lanes,
+				 LANE_NUM_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4,
+				 lanes << LANE_NUM_DP_TRANS_P0_SHIFT,
+			   LANE_NUM_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int link_rate_to_mb_per_s(struct mtk_dp *mtk_dp,
+				 enum mtk_dp_linkrate linkrate)
+{
+	switch (linkrate) {
+	case MTK_DP_LINKRATE_RBR:
+		return 1620;
+	case MTK_DP_LINKRATE_HBR:
+		return 2700;
+	case MTK_DP_LINKRATE_HBR2:
+		return 5400;
+	case MTK_DP_LINKRATE_HBR3:
+		return 8100;
+	default:
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, unknown linkrate %d\n",
+			linkrate);
+		return -EINVAL;
+	}
+}
+
+static u32 check_cal_data_valid(struct mtk_dp *mtk_dp, u32 min, u32 max, u32 val, u32 default_val)
+{
+	if (val < min || val > max)
+		dev_warn(mtk_dp->dev, "Invalid calibration data: %d (< %d || > %d), returning default %d\n",
+			 val, min, max, default_val);
+		return default_val;
+
+	return val;
+}
+
+static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
+{
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+	struct device *dev = mtk_dp->dev;
+	struct nvmem_cell *cell;
+	u32 *buf;
+	size_t len;
+
+	cell = nvmem_cell_get(dev, "dp_calibration_data");
+	if (IS_ERR(cell)) {
+		dev_err(dev,
+			"Error: Failed to get nvmem cell dp_calibration_data\n");
+		return PTR_ERR(cell);
+	}
+
+	buf = (u32 *)nvmem_cell_read(cell, &len);
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) {
+		dev_err(dev,
+			"Error: Failed to read nvmem_cell_read fail len %ld\n",
+			(len / sizeof(u32)));
+		return PTR_ERR(buf);
+	}
+
+	cal_data->ln_tx_impsel_nmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_nmos)
+		return -ENOMEM;
+
+	cal_data->ln_tx_impsel_pmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_pmos)
+		return -ENOMEM;
+
+	cal_data->glb_bias_trim =
+		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+	cal_data->clktx_impse =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int mtk_dp_set_cal_data(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_DPAUX_TX,
+				 cal_data->clktx_impse << 20, RG_CKM_PT0_CKTX_IMPSEL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_BIAS_GEN_00,
+				 cal_data->glb_bias_trim << 16,
+			   RG_XTP_GLB_BIAS_INTR_CTRL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_pmos[0] << 12,
+			   RG_XTP_LN0_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_nmos[0] << 16,
+			   RG_XTP_LN0_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_pmos[1] << 12,
+			   RG_XTP_LN1_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_nmos[1] << 16,
+			   RG_XTP_LN1_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_pmos[2] << 12,
+			   RG_XTP_LN2_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_nmos[2] << 16,
+			   RG_XTP_LN2_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_pmos[3] << 12,
+			   RG_XTP_LN3_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_nmos[3] << 16,
+			   RG_XTP_LN3_TX_IMPSEL_NMOS);
+
+	return ret;
+}
+
+static int mtk_dp_phy_configure(struct mtk_dp *mtk_dp,
+				enum mtk_dp_linkrate link_rate, int lane_count)
+{
+	int ret;
+	union phy_configure_opts phy_opts = {
+		.dp = {
+			.link_rate = link_rate_to_mb_per_s(mtk_dp, link_rate),
+			.set_rate = 1,
+			.lanes = lane_count,
+			.set_lanes = 1,
+			.ssc = mtk_dp->train_info.sink_ssc,
+		}
+		};
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP,
+				 DP_PWR_STATE_MASK);
+	if (ret)
+		return ret;
+
+	ret = phy_configure(mtk_dp->phy, &phy_opts);
+
+	if (ret)
+		return ret;
+
+	mtk_dp_set_cal_data(mtk_dp);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_idle_pattern(struct mtk_dp *mtk_dp, bool enable)
+{
+	const u32 val = POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK;
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3580, enable ? val : 0, val);
+}
+
+static int mtk_dp_train_set_pattern(struct mtk_dp *mtk_dp, int pattern)
+{
+	int ret;
+
+	if (pattern < 0 || pattern > 4) {
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, no such pattern %d\n", pattern);
+		return -EINVAL;
+	}
+
+	if (pattern == 1) { /* TPS1 */
+		ret = mtk_dp_set_idle_pattern(mtk_dp, false);
+		if (ret)
+			return ret;
+	}
+
+	return mtk_dp_update_bits(mtk_dp,
+			   MTK_DP_TRANS_P0_3400,
+			   pattern ? BIT(pattern - 1) << PATTERN1_EN_DP_TRANS_P0_SHIFT : 0,
+			   PATTERN1_EN_DP_TRANS_P0_MASK | PATTERN2_EN_DP_TRANS_P0_MASK |
+			   PATTERN3_EN_DP_TRANS_P0_MASK |
+			   PATTERN4_EN_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_set_enhanced_frame_mode(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
+			   enable ? BIT(ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT) : 0,
+			   ENHANCED_FRAME_EN_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3404,
+			   enable ? DP_SCR_EN_DP_TRANS_P0_MASK : 0,
+			   DP_SCR_EN_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
+
+	if (enable)
+		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
+			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+}
+
+static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, 0,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	/* Wait for power enable */
+	usleep_range(10, 200);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, SW_RST_B_PHYD,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL,
+			   DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
+			   DA_CKM_CKTX0_EN_FORCE_EN | DA_CKM_BIAS_LPF_EN_FORCE_VAL |
+		     DA_CKM_BIAS_EN_FORCE_VAL |
+		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
+		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
+
+	if (ret)
+		return ret;
+
+	/* Disable RX */
+	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
+			   0x550 | BIT(FUSE_SEL_SHIFT) | BIT(MEM_ISO_EN_SHIFT));
+
+	return ret;
+}
+
+static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
+{
+	mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR2;
+	mtk_dp->train_info.lane_count = mtk_dp->max_lanes;
+	mtk_dp->train_info.irq_status = 0;
+	mtk_dp->train_info.cable_plugged_in = false;
+	mtk_dp->train_info.cable_state_change = false;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	mtk_dp->state = MTK_DP_STATE_INITIAL;
+
+	mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+	mtk_dp->info.depth = MTK_DP_COLOR_DEPTH_8BIT;
+	memset(&mtk_dp->info.timings, 0, sizeof(struct mtk_dp_timings));
+	mtk_dp->info.timings.frame_rate = 60;
+
+	mtk_dp->has_fec = false;
+}
+
+static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
+{
+	u32 sram_read_start = MTK_DP_TBC_BUF_READ_START_ADDR;
+
+	if (mtk_dp->train_info.lane_count > 0) {
+		sram_read_start = min_t(u32,
+					MTK_DP_TBC_BUF_READ_START_ADDR,
+					mtk_dp->info.timings.vm.hactive /
+					mtk_dp->train_info.lane_count /
+					MTK_DP_4P1T / MTK_DP_HDE / MTK_DP_PIX_PER_ADDR);
+		mtk_dp_set_sram_read_start(mtk_dp, sram_read_start);
+	}
+
+	mtk_dp_setup_encoder(mtk_dp);
+}
+
+static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
+{
+	u8 target_frame_rate = 60;
+	u32 target_pixel_clk;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.frame_rate > 0) {
+		target_frame_rate = mtk_dp->info.timings.frame_rate;
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	} else if (mtk_dp->info.timings.pix_rate_khz > 0) {
+		target_pixel_clk = mtk_dp->info.timings.pix_rate_khz * 1000;
+	} else {
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	}
+
+	mtk_dp->info.timings.pix_rate_khz = target_pixel_clk / 1000;
+}
+
+static void mtk_dp_set_tx_out(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_msa_bypass_disable(mtk_dp);
+	mtk_dp_calculate_pixrate(mtk_dp);
+	mtk_dp_pg_disable(mtk_dp);
+	mtk_dp_setup_tu(mtk_dp);
+}
+
+static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
+{
+	ssize_t ret;
+	u8 sink_count;
+	bool locked;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+	u32 sink_count_reg = DP_SINK_COUNT_ESI;
+	u32 link_status_reg = DP_LANE0_1_STATUS;
+
+	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg, &sink_count);
+	if (ret < 0) {
+		drm_err(mtk_dp->drm_dev, "Read sink count failed: %ld\n", ret);
+		return ret;
+	}
+
+	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg, link_status,
+			       sizeof(link_status));
+	if (!ret) {
+		drm_err(mtk_dp->drm_dev, "Read link status failed: %ld\n",
+			ret);
+		return ret;
+	}
+
+	locked = drm_dp_channel_eq_ok(link_status,
+				      mtk_dp->train_info.lane_count);
+	if (!locked && mtk_dp->train_state > MTK_DP_TRAIN_STATE_TRAINING_PRE)
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+
+	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR,
+				   DP_REMOTE_CONTROL_COMMAND_PENDING);
+
+	if (DP_GET_SINK_COUNT(sink_count) &&
+	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
+		mtk_dp->train_info.check_cap_count = 0;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+		msleep(20);
+	}
+
+	return 0;
+}
+
+static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
+					  u8 dpcd_adjust_req[2])
+{
+	int lane;
+
+	for (lane = 0; lane < lanes; ++lane) {
+		u8 val;
+		u8 swing;
+		u8 preemphasis;
+		int index = lane / 2;
+		int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
+
+		swing = (dpcd_adjust_req[index] >> shift) &
+			DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
+		preemphasis = ((dpcd_adjust_req[index] >> shift) &
+			       DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
+			      DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
+		val = swing << DP_TRAIN_VOLTAGE_SWING_SHIFT |
+		      preemphasis << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+		if (swing == DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
+			val |= DP_TRAIN_MAX_SWING_REACHED;
+		if (preemphasis == 3)
+			val |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+		mtk_dp_set_swing_pre_emphasis(mtk_dp, lane, swing, preemphasis);
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_LANE0_SET + lane,
+				   val);
+	}
+}
+
+static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
+				    u8 link_status[DP_LINK_STATUS_SIZE])
+{
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
+			 DP_LINK_STATUS_SIZE);
+}
+
+static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
+			      u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, false);
+	if (ret)
+		return ret;
+
+	if (*status_control == 0) {
+		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
+		if (ret)
+			return ret;
+
+		val = DP_LINK_SCRAMBLING_DISABLE |
+			DP_TRAINING_PATTERN_1;
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_1);
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 1;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
+					       mtk_dp->rx_cap);
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (drm_dp_clock_recovery_ok(link_status,
+				     target_lane_count)) {
+		mtk_dp->train_info.cr_done = true;
+		*iteration_count = 1;
+		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
+		return 0;
+	} else if (*prev_lane_adjust == link_status[4]) {
+		(*iteration_count)++;
+		if (*prev_lane_adjust & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
+			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
+			return -EINVAL;
+		}
+	} else {
+		*prev_lane_adjust = link_status[4];
+	}
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8 target_linkrate,
+				u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	if (*status_control == 1) {
+		if (mtk_dp->train_info.tps4) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_TRAINING_PATTERN_4;
+		} else if (mtk_dp->train_info.tps3) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_3;
+		} else {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_2;
+		}
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				val);
+
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 2;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
+					   mtk_dp->rx_cap);
+
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (!drm_dp_clock_recovery_ok(link_status,
+				      target_lane_count)) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
+		return -EINVAL;
+	}
+
+	if (drm_dp_channel_eq_ok(link_status,
+				 target_lane_count)) {
+		mtk_dp->train_info.eq_done = true;
+		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
+		return 0;
+	}
+
+	if (*prev_lane_adjust == link_status[4])
+		(*iteration_count)++;
+	else
+		*prev_lane_adjust = link_status[4];
+
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_flow(struct mtk_dp *mtk_dp, u8 target_link_rate,
+			     u8 target_lane_count)
+{
+	u8 lane_adjust[2] = {};
+	bool pass_tps1 = false;
+	bool pass_tps2_3 = false;
+	int train_retries;
+	int status_control;
+	int iteration_count;
+	int ret;
+	u8 prev_lane_adjust;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LINK_BW_SET, target_link_rate);
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count | DP_LANE_COUNT_ENHANCED_FRAME_EN);
+
+	if (mtk_dp->train_info.sink_ssc)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DOWNSPREAD_CTRL,
+				   DP_SPREAD_AMP_0_5);
+
+	train_retries = 0;
+	status_control = 0;
+	iteration_count = 1;
+	prev_lane_adjust = 0xFF;
+
+	mtk_dp_set_lanes(mtk_dp, target_lane_count / 2);
+	ret = mtk_dp_phy_configure(mtk_dp, target_link_rate, target_lane_count);
+	if (ret)
+		return -EINVAL;
+
+	dev_dbg(mtk_dp->dev,
+		"Link train target_link_rate = 0x%x, target_lane_count = 0x%x\n",
+		target_link_rate, target_lane_count);
+
+	do {
+		train_retries++;
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    ((mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) !=
+		     0x0)) {
+			return -ENODEV;
+		}
+
+		if (mtk_dp->train_state < MTK_DP_TRAIN_STATE_TRAINING)
+			return -EAGAIN;
+
+		if (!pass_tps1) {
+			ret = mtk_dp_train_tps_1(mtk_dp, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps1 = true;
+				train_retries = 0;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		} else {
+			ret = mtk_dp_train_tps_2_3(mtk_dp, target_link_rate, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps2_3 = true;
+				break;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		}
+
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_ADJUST_REQUEST_LANE0_1,
+				 lane_adjust, sizeof(lane_adjust));
+		mtk_dp_train_update_swing_pre(mtk_dp, target_lane_count,
+					      lane_adjust);
+	} while (train_retries < MTK_DP_TRAIN_RETRY_LIMIT &&
+		 iteration_count < MTK_DP_TRAIN_MAX_ITERATIONS);
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET,
+			   DP_TRAINING_PATTERN_DISABLE);
+	ret = mtk_dp_train_set_pattern(mtk_dp, 0);
+	if (ret)
+		return -EINVAL;
+
+	if (!pass_tps2_3)
+		return -ETIMEDOUT;
+
+	mtk_dp->train_info.link_rate = target_link_rate;
+	mtk_dp->train_info.lane_count = target_lane_count;
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, true);
+	if (ret)
+		return ret;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count |
+				   DP_LANE_COUNT_ENHANCED_FRAME_EN);
+	ret = mtk_dp_set_enhanced_frame_mode(mtk_dp, true);
+
+	return ret;
+}
+
+static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+{
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+	u8 val;
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	if (!mtk_dp_plug_state(mtk_dp))
+		return false;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
+	/* Wait for power on */
+	usleep_range(2000, 5000);
+
+	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+
+	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap), sizeof(buf)));
+	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &= DP_TRAINING_AUX_RD_MASK;
+
+	train_info->link_rate =
+		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp->max_linkrate]);
+	train_info->lane_count =
+		min_t(int, mtk_dp->max_lanes, drm_dp_max_lane_count(buf));
+
+	train_info->tps3 = drm_dp_tps3_supported(buf);
+	train_info->tps4 = drm_dp_tps4_supported(buf);
+
+	train_info->sink_ssc =
+		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
+
+	train_info->sink_ssc = false;
+
+	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
+	if (val & DP_MST_CAP) {
+		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
+		drm_dp_dpcd_readb(&mtk_dp->aux,
+				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, &val);
+		if (val)
+			drm_dp_dpcd_writeb(&mtk_dp->aux,
+					   DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
+					   val);
+	}
+
+	return true;
+}
+
+static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
+{
+	phy_reset(mtk_dp->phy);
+	mtk_dp_reset_swing_pre_emphasis(mtk_dp);
+}
+
+static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+	u8 lane_count;
+	u8 link_rate;
+	u8 train_limit;
+	u8 max_link_rate;
+	u8 plug_wait;
+
+	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait > 0;
+	     --plug_wait)
+		/* Avoid short pulses on the HPD isr */
+		usleep_range(1000, 5000);
+	if (plug_wait == 0) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+		return -ENODEV;
+	}
+
+	link_rate = mtk_dp->rx_cap[1];
+	lane_count = mtk_dp->rx_cap[2] & 0x1F;
+
+	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate, link_rate);
+	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes, lane_count);
+	link_rate = mtk_dp->train_info.link_rate;
+	lane_count = mtk_dp->train_info.lane_count;
+
+	switch (link_rate) {
+	case MTK_DP_LINKRATE_RBR:
+	case MTK_DP_LINKRATE_HBR:
+	case MTK_DP_LINKRATE_HBR2:
+	case MTK_DP_LINKRATE_HBR25:
+	case MTK_DP_LINKRATE_HBR3:
+		break;
+	default:
+		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
+		break;
+	};
+
+	max_link_rate = link_rate;
+	for (train_limit = 6; train_limit > 0; train_limit--) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+
+		mtk_dp_train_change_mode(mtk_dp);
+		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
+		if (ret)
+			return ret;
+
+		if (!mtk_dp->train_info.cr_done) {
+			switch (link_rate) {
+			case MTK_DP_LINKRATE_RBR:
+				lane_count = lane_count / 2;
+				link_rate = max_link_rate;
+				if (lane_count == 0) {
+					mtk_dp->train_state =
+						MTK_DP_TRAIN_STATE_DPIDLE;
+					return -EIO;
+				}
+				break;
+			case MTK_DP_LINKRATE_HBR:
+				link_rate = MTK_DP_LINKRATE_RBR;
+				break;
+			case MTK_DP_LINKRATE_HBR2:
+				link_rate = MTK_DP_LINKRATE_HBR;
+				break;
+			case MTK_DP_LINKRATE_HBR3:
+				link_rate = MTK_DP_LINKRATE_HBR2;
+				break;
+			default:
+				return -EINVAL;
+			};
+		} else if (!mtk_dp->train_info.eq_done) {
+			if (lane_count == 0)
+				return -EIO;
+
+			lane_count /= 2;
+		} else {
+			break;
+		}
+	}
+
+	if (train_limit == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+//TODO: check drm_dp_helpers for duplicated code
+
+static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	if (enable) {
+		mtk_dp_set_tx_out(mtk_dp);
+		mtk_dp_video_mute(mtk_dp, false);
+	} else {
+		mtk_dp_video_mute(mtk_dp, true);
+	}
+}
+
+static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_mn_overwrite_disable(mtk_dp);
+
+	mtk_dp_set_msa(mtk_dp);
+
+	mtk_dp_set_color_depth(mtk_dp, mtk_dp->info.depth);
+	mtk_dp_set_color_format(mtk_dp, mtk_dp->info.format);
+}
+
+static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
+{
+	switch (mtk_dp->state) {
+	case MTK_DP_STATE_INITIAL:
+		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp->state = MTK_DP_STATE_IDLE;
+		break;
+
+	case MTK_DP_STATE_IDLE:
+		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
+			mtk_dp->state = MTK_DP_STATE_PREPARE;
+		break;
+
+	case MTK_DP_STATE_PREPARE:
+		mtk_dp_video_config(mtk_dp);
+		mtk_dp_video_enable(mtk_dp, true);
+
+		mtk_dp->state = MTK_DP_STATE_NORMAL;
+		break;
+
+	case MTK_DP_STATE_NORMAL:
+		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
+			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp->state = MTK_DP_STATE_IDLE;
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
+{
+	bool training_done = false;
+	short max_retry = 50;
+	int ret = 0;
+
+	do {
+		switch (mtk_dp->train_state) {
+		case MTK_DP_TRAIN_STATE_STARTUP:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKCAP:
+			if (mtk_dp_parse_capabilities(mtk_dp)) {
+				mtk_dp->train_info.check_cap_count = 0;
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+			} else {
+				mtk_dp->train_info.check_cap_count++;
+
+				if (mtk_dp->train_info.check_cap_count >
+				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT) {
+					mtk_dp->train_info.check_cap_count = 0;
+					mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+					ret = -ETIMEDOUT;
+				}
+			}
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKEDID:
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING:
+			ret = mtk_dp_train_start(mtk_dp);
+			if (ret == 0) {
+				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
+				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
+			} else if (ret != -EAGAIN) {
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+			}
+			break;
+		case MTK_DP_TRAIN_STATE_NORMAL:
+			mtk_dp_state_handler(mtk_dp);
+			training_done = true;
+			break;
+		case MTK_DP_TRAIN_STATE_DPIDLE:
+			break;
+		default:
+			break;
+		}
+
+		if (ret) {
+			if (ret == -EAGAIN)
+				continue;
+			/*
+			 * If we get any other error number, it doesn't
+			 * make any sense to keep iterating.
+			 */
+			break;
+		}
+	} while (!training_done || --max_retry);
+
+	return ret;
+}
+
+static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_set_idle_pattern(mtk_dp, true);
+	mtk_dp_initialize_priv_data(mtk_dp);
+
+	mtk_dp_initialize_settings(mtk_dp);
+	mtk_dp_initialize_aux_settings(mtk_dp);
+	mtk_dp_initialize_digital_settings(mtk_dp);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690,
+			   BIT(RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT),
+			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK);
+	mtk_dp_initialize_hpd_detect_settings(mtk_dp);
+
+	mtk_dp_digital_sw_reset(mtk_dp);
+}
+
+static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	int event;
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+
+	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected :
+						  connector_status_disconnected;
+
+	if (event < 0)
+		return IRQ_HANDLED;
+
+	if (mtk_dp->drm_dev) {
+		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
+		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
+	}
+
+	if (mtk_dp->train_info.cable_state_change) {
+		mtk_dp->train_info.cable_state_change = false;
+
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    !mtk_dp_plug_state(mtk_dp)) {
+			mtk_dp_video_mute(mtk_dp, true);
+
+			mtk_dp_initialize_priv_data(mtk_dp);
+			mtk_dp_set_idle_pattern(mtk_dp, true);
+			if (mtk_dp->has_fec)
+				mtk_dp_fec_enable(mtk_dp, false);
+
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL,
+					   DP_PWR_STATE_MASK);
+		} else {
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL_LANE,
+					   DP_PWR_STATE_MASK);
+			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+			mtk_dp->train_info.link_rate =
+				min_t(int, mtk_dp->max_linkrate,
+				      buf[mtk_dp->max_linkrate]);
+			mtk_dp->train_info.lane_count =
+				min_t(int, mtk_dp->max_lanes,
+				      drm_dp_max_lane_count(buf));
+		}
+	}
+
+	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
+		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
+		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
+		mtk_dp_hpd_sink_event(mtk_dp);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
+{
+	bool connected;
+	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
+	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	train_info->irq_status |= hwirq_status | swirq_status;
+
+	if (!train_info->irq_status)
+		return IRQ_HANDLED;
+
+	connected = mtk_dp_plug_state(mtk_dp);
+	if (connected || !train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+	else if (!connected || train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;
+
+	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+		train_info->cable_plugged_in = true;
+	} else {
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+		train_info->cable_plugged_in = false;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	}
+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	u32 irq_status;
+
+	irq_status = mtk_dp_read(mtk_dp, MTK_DP_TOP_IRQ_STATUS);
+
+	if (!irq_status)
+		return IRQ_HANDLED;
+
+	if (irq_status & RGS_IRQ_STATUS_TRANSMITTER)
+		return mtk_dp_hpd_isr_handler(mtk_dp);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
+			   struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	mtk_dp->regs = devm_regmap_init_mmio(dev, base, &mtk_dp_regmap_config);
+	if (IS_ERR(mtk_dp->regs))
+		return PTR_ERR(mtk_dp->regs);
+
+	mtk_dp->dp_tx_clk = devm_clk_get(dev, "faxi");
+	if (IS_ERR(mtk_dp->dp_tx_clk)) {
+		dev_err(dev, "Failed to get dptx clock: %d\n", ret);
+		mtk_dp->dp_tx_clk = NULL;
+		return PTR_ERR(mtk_dp->dp_tx_clk);
+	}
+
+	ret = device_property_read_u8(dev, "max-lanes", &mtk_dp->max_lanes);
+	if (ret)
+		return ret;
+
+	ret = device_property_read_u8(dev, "max-linkrate", &mtk_dp->max_linkrate);
+
+	return ret;
+}
+
+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 enabled = mtk_dp->enabled;
+	struct edid *new_edid = NULL;
+
+//TODO: refcount enabled so that we don't have any surprises...
+
+	if (!enabled)
+		drm_bridge_chain_pre_enable(bridge);
+
+	if (mtk_dp_plug_state(mtk_dp))
+		new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc);
+
+	if (!enabled)
+		drm_bridge_chain_post_disable(bridge);
+
+	return new_edid;
+}
+
+static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+				   struct drm_dp_aux_msg *msg)
+{
+	struct mtk_dp *mtk_dp;
+	bool is_read;
+	u8 request;
+	size_t accessed_bytes = 0;
+	int ret = 0;
+
+	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
+
+	if (!mtk_dp->train_info.cable_plugged_in ||
+	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+		return -EAGAIN;
+	}
+
+	switch (msg->request) {
+	case DP_AUX_I2C_MOT:
+	case DP_AUX_I2C_WRITE:
+	case DP_AUX_NATIVE_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
+		request = msg->request & ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
+		is_read = false;
+		break;
+	case DP_AUX_I2C_READ:
+	case DP_AUX_NATIVE_READ:
+	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
+		request = msg->request;
+		is_read = true;
+		break;
+	default:
+		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
+			msg->request);
+		return -EINVAL;
+	}
+
+	if (msg->size == 0) {
+		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
+					     msg->address + accessed_bytes,
+					     msg->buffer + accessed_bytes, 0);
+	} else {
+		while (accessed_bytes < msg->size) {
+			size_t to_access =
+				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
+				      msg->size - accessed_bytes);
+
+			ret = mtk_dp_aux_do_transfer(mtk_dp,
+						     is_read, request,
+							 msg->address + accessed_bytes,
+							 msg->buffer + accessed_bytes,
+							 to_access);
+
+			if (ret) {
+				drm_info(mtk_dp->drm_dev,
+					 "Failed to do AUX transfer: %d\n", ret);
+				break;
+			}
+			accessed_bytes += to_access;
+		}
+	}
+
+	if (ret) {
+		msg->reply = DP_AUX_NATIVE_REPLY_NACK | DP_AUX_I2C_REPLY_NACK;
+		return ret;
+	}
+
+	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
+	return msg->size;
+}
+
+static void mtk_dp_poweroff(struct mtk_dp *mtk_dp)
+{
+	mutex_lock(&mtk_dp->dp_lock);
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+	mtk_dp_power_disable(mtk_dp);
+	phy_exit(mtk_dp->phy);
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+
+	mutex_unlock(&mtk_dp->dp_lock);
+}
+
+static int mtk_dp_poweron(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->dp_lock);
+
+	ret = clk_prepare_enable(mtk_dp->dp_tx_clk);
+	if (ret < 0) {
+		dev_err(mtk_dp->dev, "Fail to enable clock: %d\n", ret);
+		goto err;
+	}
+	ret = phy_init(mtk_dp->phy);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to initialize phy: %d\n", ret);
+		goto err_phy_init;
+	}
+	ret = mtk_dp_phy_configure(mtk_dp, MTK_DP_LINKRATE_RBR, 1);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to configure phy: %d\n", ret);
+		goto err_phy_config;
+	}
+
+	mtk_dp_init_port(mtk_dp);
+	ret = mtk_dp_power_enable(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+
+err_phy_config:
+	phy_exit(mtk_dp->phy);
+err_phy_init:
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+err:
+	mutex_unlock(&mtk_dp->dp_lock);
+	return ret;
+}
+
+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;
+
+	ret = mtk_dp_poweron(mtk_dp);
+	if (ret)
+		return ret;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mtk_dp->dev, "Driver does not provide a connector!");
+		return -EINVAL;
+	}
+
+	if (mtk_dp->next_bridge) {
+		ret = drm_bridge_attach(bridge->encoder, mtk_dp->next_bridge,
+					&mtk_dp->bridge, flags);
+		if (ret) {
+			drm_warn(mtk_dp->drm_dev,
+				 "Failed to attach external bridge: %d\n", ret);
+			return ret;
+		}
+	}
+
+	mtk_dp->drm_dev = bridge->dev;
+
+	return 0;
+}
+
+static void mtk_dp_bridge_detach(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->drm_dev = NULL;
+}
+
+static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp->state = MTK_DP_STATE_IDLE;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+	mtk_dp->enabled = false;
+	/* Ensure the sink is muted before powering off */
+	msleep(100);
+	mtk_dp_poweroff(mtk_dp);
+}
+
+static void mtk_dp_parse_drm_mode_timings(struct mtk_dp *mtk_dp,
+					  struct drm_display_mode *mode)
+{
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_to_videomode(mode, &timings->vm);
+	timings->frame_rate = drm_mode_vrefresh(mode);
+}
+
+static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
+					struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->conn = drm_atomic_get_new_connector_for_encoder(old_state->base.state,
+								bridge->encoder);
+	if (!mtk_dp->conn) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector is missing\n");
+		return;
+	}
+
+	/* Training */
+	if (mtk_dp_train_handler(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev, "Training failed\n");
+		return;
+	}
+
+	mtk_dp->enabled = true;
+}
+
+static enum drm_mode_status
+mtk_dp_bridge_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+	u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24;
+
+	if (rx_linkrate * mtk_dp->train_info.lane_count < mode->clock * bpp / 8)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock > 600000)
+		return MODE_CLOCK_HIGH;
+
+	if ((mode->clock * 1000) / (mode->htotal * mode->vtotal) > MTK_VDOSYS1_MAX_FRAMERATE)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *output_fmts;
+
+	*num_output_fmts = 0;
+	output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL);
+	if (!output_fmts)
+		return NULL;
+	*num_output_fmts = 1;
+	output_fmts[0] = MEDIA_BUS_FMT_FIXED;
+	return output_fmts;
+}
+
+static const u32 mt8195_input_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *input_fmts;
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+	struct drm_display_info *display_info =
+		&conn_state->connector->display_info;
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+
+	*num_input_fmts = 0;
+
+	if (((rx_linkrate * mtk_dp->train_info.lane_count) <
+	     (mode->clock * 24 / 8)) &&
+	    ((rx_linkrate * mtk_dp->train_info.lane_count) >
+	     (mode->clock * 16 / 8)) &&
+	    (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+		input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+		*num_input_fmts = 1;
+		input_fmts[0] = MEDIA_BUS_FMT_YUYV8_1X16;
+	} else {
+		input_fmts = kcalloc(ARRAY_SIZE(mt8195_input_fmts), sizeof(*input_fmts),
+				     GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+
+		*num_input_fmts = ARRAY_SIZE(mt8195_input_fmts);
+		memcpy(input_fmts, mt8195_input_fmts, sizeof(mt8195_input_fmts));
+	}
+
+	return input_fmts;
+}
+
+static int mtk_dp_bridge_atomic_check(struct drm_bridge *bridge,
+				      struct drm_bridge_state *bridge_state,
+				      struct drm_crtc_state *crtc_state,
+				      struct drm_connector_state *conn_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_crtc *crtc = conn_state->crtc;
+	unsigned int input_bus_format;
+
+	input_bus_format = bridge_state->input_bus_cfg.format;
+
+	dev_dbg(mtk_dp->dev, "input format 0x%04x, output format 0x%04x\n",
+		bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
+
+	mtk_dp->input_fmt = input_bus_format;
+	if (mtk_dp->input_fmt == MEDIA_BUS_FMT_YUYV8_1X16)
+		mtk_dp->info.format = DP_PIXELFORMAT_YUV422;
+	else
+		mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+
+	if (!crtc) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector state doesn't have a crtc\n");
+		return -EINVAL;
+	}
+
+	mtk_dp_parse_drm_mode_timings(mtk_dp, &crtc_state->adjusted_mode);
+	if (!mtk_dp_parse_capabilities(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as nothing is plugged in\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
+	.atomic_check = mtk_dp_bridge_atomic_check,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_get_output_bus_fmts = mtk_dp_bridge_atomic_get_output_bus_fmts,
+	.atomic_get_input_bus_fmts = mtk_dp_bridge_atomic_get_input_bus_fmts,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.attach = mtk_dp_bridge_attach,
+	.detach = mtk_dp_bridge_detach,
+	.atomic_enable = mtk_dp_bridge_atomic_enable,
+	.atomic_disable = mtk_dp_bridge_atomic_disable,
+	.mode_valid = mtk_dp_bridge_mode_valid,
+	.get_edid = mtk_dp_get_edid,
+};
+
+static int mtk_dp_probe(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp;
+	struct device *dev = &pdev->dev;
+	int ret;
+	int irq_num = 0;
+
+	mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
+	if (!mtk_dp)
+		return -ENOMEM;
+
+	mtk_dp->dev = dev;
+
+	irq_num = platform_get_irq(pdev, 0);
+	if (irq_num < 0)
+		return dev_err_probe(dev, irq_num, "failed to request dp irq resource\n");
+
+	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+	if (IS_ERR(mtk_dp->next_bridge)) {
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
+	}
+
+	ret = mtk_dp_dt_parse(mtk_dp, pdev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to parse dt\n");
+
+	drm_dp_aux_init(&mtk_dp->aux);
+	mtk_dp->aux.name = "aux_mtk_dp";
+	mtk_dp->aux.transfer = mtk_dp_aux_transfer;
+
+	ret = devm_request_threaded_irq(dev, irq_num, mtk_dp_hpd_event,
+					mtk_dp_hpd_event_thread,
+					IRQ_TYPE_LEVEL_HIGH, dev_name(dev),
+					mtk_dp);
+	if (ret)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
+
+	mutex_init(&mtk_dp->dp_lock);
+
+	platform_set_drvdata(pdev, mtk_dp);
+
+	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
+							PLATFORM_DEVID_AUTO,
+							&mtk_dp->regs,
+							sizeof(struct regmap *));
+	if (IS_ERR(mtk_dp->phy_dev))
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev), "Failed to create device mediatek-dp-phy\n");
+
+	mtk_dp_get_calibration_data(mtk_dp);
+
+	mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
+
+	if (IS_ERR(mtk_dp->phy)) {
+		platform_device_unregister(mtk_dp->phy_dev);
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n");
+	}
+
+	mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
+	mtk_dp->bridge.of_node = dev->of_node;
+
+	mtk_dp->bridge.ops =
+		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
+	drm_bridge_add(&mtk_dp->bridge);
+	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_remove(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp = platform_get_drvdata(pdev);
+
+	platform_device_unregister(mtk_dp->phy_dev);
+	mtk_dp_video_mute(mtk_dp, true);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_dp_suspend(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
+		/* Ensure the sink is off before shutting down power */
+		usleep_range(2000, 3000);
+	}
+
+	ret = mtk_dp_power_disable(mtk_dp);
+	if (ret)
+		return ret;
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+
+	mtk_dp_init_port(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+	ret = mtk_dp_power_enable(mtk_dp);
+
+	return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
+
+static const struct of_device_id mtk_dp_of_match[] = {
+	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{},
+};
+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 = &mtk_dp_pm_ops,
+	},
+};
+
+MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DisplayPort Driver");
+MODULE_LICENSE("GPL");
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 000000000000..848e5f697737
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
@@ -0,0 +1,570 @@
+/* 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                                             \
+	(BIT(0) | BIT(1) | BIT(5) | BIT(8) | BIT(10) | BIT(25) | BIT(31))
+#define MTK_DP_SIP_ATF_VIDEO_UNMUTE	BIT(5)
+#define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE (BIT(0) | BIT(5))
+
+#define DP_PHY_GLB_BIAS_GEN_00	  0
+#define RG_XTP_GLB_BIAS_INTR_CTRL GENMASK(20, 16)
+
+#define DP_PHY_GLB_DPAUX_TX    BIT(3)
+#define RG_CKM_PT0_CKTX_IMPSEL GENMASK(23, 20)
+
+#define DP_PHY_LANE_TX_0	  (BIT(2) | BIT(8))
+#define RG_XTP_LN0_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN0_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_1	  (BIT(2) | BIT(9))
+#define RG_XTP_LN1_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN1_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_2	  (BIT(2) | BIT(8) | BIT(9))
+#define RG_XTP_LN2_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN2_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_3	  (BIT(2) | BIT(10))
+#define RG_XTP_LN3_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN3_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define TOP_OFFSET   BIT(13)
+#define ENC0_OFFSET  GENMASK(13, 12)
+#define ENC1_OFFSET  (BIT(9) | BIT(12) | BIT(13))
+#define TRANS_OFFSET (BIT(10) | BIT(12) | BIT(13))
+#define AUX_OFFSET   (BIT(9) | BIT(10) | BIT(12) | BIT(13))
+#define SEC_OFFSET   BIT(14)
+
+#define MTK_DP_HPD_DISCONNECT BIT(1)
+#define MTK_DP_HPD_CONNECT    BIT(2)
+#define MTK_DP_HPD_INTERRUPT  BIT(3)
+
+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
+#define DA_XTP_GLB_CKDET_EN_FORCE_VAL BIT(15)
+#define DA_XTP_GLB_CKDET_EN_FORCE_EN  BIT(14)
+#define DA_CKM_INTCKTX_EN_FORCE_VAL   BIT(13)
+#define DA_CKM_INTCKTX_EN_FORCE_EN    BIT(12)
+#define DA_CKM_CKTX0_EN_FORCE_VAL     BIT(11)
+#define DA_CKM_CKTX0_EN_FORCE_EN      BIT(10)
+#define DA_CKM_XTAL_CK_FORCE_VAL      BIT(9)
+#define DA_CKM_XTAL_CK_FORCE_EN	      BIT(8)
+#define DA_CKM_BIAS_LPF_EN_FORCE_VAL  BIT(7)
+#define DA_CKM_BIAS_LPF_EN_FORCE_EN   BIT(6)
+#define DA_CKM_BIAS_EN_FORCE_VAL      BIT(5)
+#define DA_CKM_BIAS_EN_FORCE_EN	      BIT(4)
+#define DA_XTP_GLB_AVD10_ON_FORCE_VAL BIT(3)
+#define DA_XTP_GLB_AVD10_ON_FORCE     BIT(2)
+#define DA_XTP_GLB_LDO_EN_FORCE_VAL   BIT(1)
+#define DA_XTP_GLB_LDO_EN_FORCE_EN    BIT(0)
+
+#define MTK_DP_1040		      (BIT(6) | BIT(12))
+#define RG_DPAUX_RX_VALID_DEGLITCH_EN BIT(2)
+#define RG_XTP_GLB_CKDET_EN	      BIT(1)
+#define RG_DPAUX_RX_EN		      BIT(0)
+
+#define MTK_DP_ENC0_P0_3000		   (ENC0_OFFSET + 0x00)
+#define LANE_NUM_DP_ENC0_P0_MASK	   GENMASK(1, 0)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_MASK	   BIT(2)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT	   BIT(1)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_MASK	   BIT(3)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT	   GENMASK(1, 0)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_MASK  BIT(4)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT BIT(2)
+
+#define MTK_DP_ENC0_P0_3004			   (ENC0_OFFSET + 0x04)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK	   BIT(8)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_SHIFT	   BIT(3)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK  BIT(9)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT (BIT(0) | BIT(3))
+
+#define MTK_DP_ENC0_P0_3008		  (ENC0_OFFSET + 0x08)
+#define VIDEO_M_CODE_SW_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_300C		  (ENC0_OFFSET + 0x0C)
+#define VIDEO_M_CODE_SW_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3010	  (ENC0_OFFSET + 0x10)
+#define HTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3014	  (ENC0_OFFSET + 0x14)
+#define VTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3018	  (ENC0_OFFSET + 0x18)
+#define HSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_301C	  (ENC0_OFFSET + 0x1C)
+#define VSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3020	  (ENC0_OFFSET + 0x20)
+#define HWIDTH_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3024	   (ENC0_OFFSET + 0x24)
+#define VHEIGHT_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3028	(ENC0_OFFSET + 0x28)
+#define HSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define HSW_SW_DP_ENC0_P0_SHIFT 0
+#define HSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_302C	(ENC0_OFFSET + 0x2C)
+#define VSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define VSW_SW_DP_ENC0_P0_SHIFT 0
+#define VSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_3030			 (ENC0_OFFSET + 0x30)
+#define HTOTAL_SEL_DP_ENC0_P0_SHIFT		 0
+#define VTOTAL_SEL_DP_ENC0_P0_SHIFT		 BIT(0)
+#define HSTART_SEL_DP_ENC0_P0_SHIFT		 BIT(1)
+#define VSTART_SEL_DP_ENC0_P0_SHIFT		 GENMASK(1, 0)
+#define HWIDTH_SEL_DP_ENC0_P0_SHIFT		 BIT(2)
+#define VHEIGHT_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(2))
+#define HSP_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 1)
+#define HSW_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 0)
+#define VSP_SEL_DP_ENC0_P0_SHIFT		 BIT(3)
+#define VSW_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK	 (BIT(11))
+#define VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT	 (BIT(0) | BIT(1) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK (BIT(12))
+#define VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT	 GENMASK(3, 2)
+
+#define MTK_DP_ENC0_P0_3034 (ENC0_OFFSET + 0x34)
+
+#define MTK_DP_ENC0_P0_3038		  (ENC0_OFFSET + 0x38)
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK  (BIT(11))
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_SHIFT (BIT(0) | BIT(1) | BIT(3))
+
+#define MTK_DP_ENC0_P0_303C		      (ENC0_OFFSET + 0x3C)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT 0
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK     GENMASK(10, 8)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT    BIT(3)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT                                     \
+	(0 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT                                     \
+	(1 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT                                     \
+	(2 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT                                      \
+	(3 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT                                      \
+	(4 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK  GENMASK(14, 12)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT GENMASK(3, 2)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB                                     \
+	(0 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422                                \
+	(1 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420                                \
+	(2 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK	 (BIT(15))
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT GENMASK(3, 0)
+
+#define MTK_DP_ENC0_P0_3040		   (ENC0_OFFSET + 0x40)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_3044	       (ENC0_OFFSET + 0x44)
+#define VIDEO_N_CODE_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3048	       (ENC0_OFFSET + 0x48)
+#define VIDEO_N_CODE_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_304C		      (ENC0_OFFSET + 0x4C)
+#define VBID_VIDEO_MUTE_DP_ENC0_P0_MASK	      BIT(2)
+#define SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK BIT(8)
+
+#define MTK_DP_ENC0_P0_3050		      (ENC0_OFFSET + 0x50)
+#define VIDEO_N_CODE_MN_GEN_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3054		      (ENC0_OFFSET + 0x54)
+#define VIDEO_N_CODE_MN_GEN_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3064	     (ENC0_OFFSET + 0x64)
+#define HDE_NUM_LAST_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3088	      (ENC0_OFFSET + 0x88)
+#define AU_EN_DP_ENC0_P0_MASK	      BIT(6)
+#define AU_EN_DP_ENC0_P0_SHIFT	      GENMASK(2, 1)
+#define AUDIO_8CH_EN_DP_ENC0_P0_MASK  BIT(7)
+#define AUDIO_8CH_SEL_DP_ENC0_P0_MASK BIT(8)
+#define AUDIO_2CH_EN_DP_ENC0_P0_MASK  (BIT(14))
+#define AUDIO_2CH_SEL_DP_ENC0_P0_MASK (BIT(15))
+
+#define MTK_DP_ENC0_P0_308C	    (ENC0_OFFSET + 0x8C)
+#define CH_STATUS_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3090	    (ENC0_OFFSET + 0x90)
+#define CH_STATUS_1_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3094	    (ENC0_OFFSET + 0x94)
+#define CH_STATUS_2_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A0 (ENC0_OFFSET + 0xA0)
+
+#define MTK_DP_ENC0_P0_30A4	  (ENC0_OFFSET + 0xA4)
+#define AU_TS_CFG_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A8 (ENC0_OFFSET + 0xA8)
+
+#define MTK_DP_ENC0_P0_30AC (ENC0_OFFSET + 0xAC)
+
+#define MTK_DP_ENC0_P0_30B0 (ENC0_OFFSET + 0xB0)
+
+#define MTK_DP_ENC0_P0_30B4	  (ENC0_OFFSET + 0xB4)
+#define ISRC_CFG_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define ISRC_CFG_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_30B8 (ENC0_OFFSET + 0xB8)
+
+#define MTK_DP_ENC0_P0_30BC			   (ENC0_OFFSET + 0xBC)
+#define ISRC_CONT_DP_ENC0_P0_MASK		   BIT(0)
+#define ISRC_CONT_DP_ENC0_P0_SHIFT		   0
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK  GENMASK(10, 8)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT BIT(3)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_2                             \
+	(1 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_4                             \
+	(2 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_8                             \
+	(3 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2                             \
+	(5 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_4                             \
+	(6 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_8                             \
+	(7 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+
+#define MTK_DP_ENC0_P0_30D8 (ENC0_OFFSET + 0xD8)
+
+#define MTK_DP_ENC0_P0_312C	 (ENC0_OFFSET + 0x12C)
+#define ASP_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define ASP_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define ASP_HB3_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_3130 (ENC0_OFFSET + 0x130)
+
+#define MTK_DP_ENC0_P0_3138 (ENC0_OFFSET + 0x138)
+
+#define MTK_DP_ENC0_P0_3154	    (ENC0_OFFSET + 0x154)
+#define PGEN_HTOTAL_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3158		  (ENC0_OFFSET + 0x158)
+#define PGEN_HSYNC_RISING_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_315C		       (ENC0_OFFSET + 0x15C)
+#define PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3160		(ENC0_OFFSET + 0x160)
+#define PGEN_HFDE_START_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3164		       (ENC0_OFFSET + 0x164)
+#define PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3168	    (ENC0_OFFSET + 0x168)
+#define PGEN_VTOTAL_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_316C		  (ENC0_OFFSET + 0x16C)
+#define PGEN_VSYNC_RISING_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3170		       (ENC0_OFFSET + 0x170)
+#define PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3174		(ENC0_OFFSET + 0x174)
+#define PGEN_VFDE_START_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3178		       (ENC0_OFFSET + 0x178)
+#define PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_31B0    (ENC0_OFFSET + 0x1B0)
+#define PGEN_PATTERN_SEL_SHIFT BIT(2)
+#define PGEN_PATTERN_SEL_MASK  GENMASK(6, 4)
+
+#define MTK_DP_ENC0_P0_31C8		  (ENC0_OFFSET + 0x1C8)
+#define VSC_EXT_VESA_HB0_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31CC		  (ENC0_OFFSET + 0x1CC)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_VESA_HB3_DP_ENC0_P0_MASK  GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D0		 (ENC0_OFFSET + 0x1D0)
+#define VSC_EXT_CEA_HB0_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31D4		 (ENC0_OFFSET + 0x1D4)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D8		  (ENC0_OFFSET + 0x1D8)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_MASK	  GENMASK(13, 8)
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_SHIFT  BIT(3)
+
+#define MTK_DP_ENC0_P0_31DC	  (ENC0_OFFSET + 0x1DC)
+#define HDR0_CFG_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define HDR0_CFG_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_31E8 (ENC0_OFFSET + 0x1E8)
+
+#define MTK_DP_ENC0_P0_31EC		  (ENC0_OFFSET + 0x1EC)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK  BIT(4)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT BIT(2)
+#define ISRC1_HB3_DP_ENC0_P0_MASK	  GENMASK(15, 8)
+#define ISRC1_HB3_DP_ENC0_P0_SHIFT	  BIT(3)
+
+#define MTK_DP_ENC1_P0_3200 (ENC1_OFFSET + 0x00)
+
+#define MTK_DP_ENC1_P0_3280		(ENC1_OFFSET + 0x80)
+#define SDP_PACKET_TYPE_DP_ENC1_P0_MASK GENMASK(4, 0)
+#define SDP_PACKET_W_DP_ENC1_P0		BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_MASK	BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_SHIFT	(BIT(0) | BIT(2))
+
+#define MTK_DP_ENC1_P0_328C (ENC1_OFFSET + 0x8C)
+
+#define MTK_DP_ENC1_P0_3290 (ENC1_OFFSET + 0x90)
+
+#define MTK_DP_ENC1_P0_32A0 (ENC1_OFFSET + 0xA0)
+
+#define MTK_DP_ENC1_P0_32A4 (ENC1_OFFSET + 0xA4)
+
+#define MTK_DP_ENC1_P0_3300		     (ENC1_OFFSET + 0x100)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC1_P0_3304			  (ENC1_OFFSET + 0x104)
+#define AU_PRTY_REGEN_DP_ENC1_P0_MASK		  BIT(8)
+#define AU_CH_STS_REGEN_DP_ENC1_P0_MASK		  BIT(9)
+#define AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK (BIT(12))
+
+#define MTK_DP_ENC1_P0_3324		  (ENC1_OFFSET + 0x124)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT BIT(3)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX                                       \
+	(0 << AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT)
+
+#define MTK_DP_ENC1_P0_3364			     (ENC1_OFFSET + 0x164)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT 0
+#define FIFO_READ_START_POINT_DP_ENC1_P0_MASK	     GENMASK(15, 12)
+#define FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT	     GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_3368			       (ENC1_OFFSET + 0x168)
+#define VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT 0
+#define VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT	       BIT(2)
+#define SDP_DP13_EN_DP_ENC1_P0_SHIFT		       BIT(3)
+#define BS2BS_MODE_DP_ENC1_P0_MASK		       GENMASK(13, 12)
+#define BS2BS_MODE_DP_ENC1_P0_SHIFT		       GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_33F4 (ENC1_OFFSET + 0x1F4)
+
+#define MTK_DP_TRANS_P0_3400	      (TRANS_OFFSET + 0)
+#define PATTERN1_EN_DP_TRANS_P0_MASK  BIT(12)
+#define PATTERN1_EN_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+#define PATTERN2_EN_DP_TRANS_P0_MASK  BIT(13)
+#define PATTERN3_EN_DP_TRANS_P0_MASK  BIT(14)
+#define PATTERN4_EN_DP_TRANS_P0_MASK  BIT(15)
+
+#define MTK_DP_TRANS_P0_3404	   (TRANS_OFFSET + 0x4)
+#define DP_SCR_EN_DP_TRANS_P0_MASK BIT(0)
+
+#define MTK_DP_TRANS_P0_340C			       (TRANS_OFFSET + 0xC)
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK (BIT(13))
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT                        \
+	(BIT(0) | BIT(2) | BIT(3))
+
+#define MTK_DP_TRANS_P0_3410		    (TRANS_OFFSET + 0x10)
+#define HPD_DEB_THD_DP_TRANS_P0_MASK	    GENMASK(3, 0)
+#define HPD_DEB_THD_DP_TRANS_P0_SHIFT	    0
+#define HPD_INT_THD_DP_TRANS_P0_MASK	    GENMASK(7, 4)
+#define HPD_INT_THD_DP_TRANS_P0_SHIFT	    BIT(2)
+#define HPD_INT_THD_DP_TRANS_P0_LOWER_500US (2 << HPD_INT_THD_DP_TRANS_P0_SHIFT)
+#define HPD_INT_THD_DP_TRANS_P0_UPPER_1100US                                   \
+	(2 << (HPD_INT_THD_DP_TRANS_P0_SHIFT + 2))
+#define HPD_DISC_THD_DP_TRANS_P0_MASK  GENMASK(11, 8)
+#define HPD_DISC_THD_DP_TRANS_P0_SHIFT BIT(3)
+#define HPD_CONN_THD_DP_TRANS_P0_MASK  GENMASK(15, 12)
+#define HPD_CONN_THD_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_3414	(TRANS_OFFSET + 0x14)
+#define HPD_DB_DP_TRANS_P0_MASK BIT(2)
+
+#define MTK_DP_TRANS_P0_3418	      (TRANS_OFFSET + 0x18)
+#define IRQ_CLR_DP_TRANS_P0_MASK      GENMASK(3, 0)
+#define IRQ_MASK_DP_TRANS_P0_MASK     GENMASK(7, 4)
+#define IRQ_MASK_DP_TRANS_P0_SHIFT    BIT(2)
+#define IRQ_MASK_DP_TRANS_P0_DISC_IRQ (BIT(1) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_CONN_IRQ (BIT(2) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_INT_IRQ  (BIT(3) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_STATUS_DP_TRANS_P0_MASK   GENMASK(15, 12)
+#define IRQ_STATUS_DP_TRANS_P0_SHIFT  GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_342C	      (TRANS_OFFSET + 0x2C)
+#define XTAL_FREQ_DP_TRANS_P0_DEFAULT (BIT(0) | BIT(3) | BIT(5) | BIT(6))
+#define XTAL_FREQ_DP_TRANS_P0_MASK    GENMASK(7, 0)
+
+#define MTK_DP_TRANS_P0_3430			   (TRANS_OFFSET + 0x30)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_MASK	   GENMASK(1, 0)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT BIT(1)
+
+#define MTK_DP_TRANS_P0_34A4	   (TRANS_OFFSET + 0xA4)
+#define LANE_NUM_DP_TRANS_P0_MASK  GENMASK(3, 2)
+#define LANE_NUM_DP_TRANS_P0_SHIFT BIT(1)
+
+#define MTK_DP_TRANS_P0_3540		    (TRANS_OFFSET + 0x140)
+#define FEC_EN_DP_TRANS_P0_MASK		    BIT(0)
+#define FEC_EN_DP_TRANS_P0_SHIFT	    0
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK  BIT(3)
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_TRANS_P0_3580			 (TRANS_OFFSET + 0x180)
+#define POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK BIT(8)
+#define POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK BIT(9)
+#define POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK (BIT(10))
+#define POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK (BIT(11))
+
+#define MTK_DP_TRANS_P0_35C4	     (TRANS_OFFSET + 0x1C4)
+#define SW_IRQ_MASK_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35C8	    (TRANS_OFFSET + 0x1C8)
+#define SW_IRQ_CLR_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define SW_IRQ_STATUS_DP_TRANS_P0_MASK	GENMASK(15, 0)
+#define SW_IRQ_STATUS_DP_TRANS_P0_SHIFT 0
+
+#define MTK_DP_TRANS_P0_35D0		     (TRANS_OFFSET + 0x1D0)
+#define SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35F0 (TRANS_OFFSET + 0x1F0)
+
+#define MTK_DP_AUX_P0_360C	       (AUX_OFFSET + 0xC)
+#define AUX_TIMEOUT_THR_AUX_TX_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_AUX_P0_3614		  (AUX_OFFSET + 0x14)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK  GENMASK(6, 0)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3618			 (AUX_OFFSET + 0x18)
+#define AUX_RX_FIFO_FULL_AUX_TX_P0_MASK		 BIT(9)
+#define AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3620		      (AUX_OFFSET + 0x20)
+#define AUX_RD_MODE_AUX_TX_P0_MASK	      BIT(9)
+#define AUX_RX_FIFO_READ_PULSE_TX_P0_MASK     BIT(8)
+#define AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT	      BIT(3)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK  GENMASK(7, 0)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3624		    (AUX_OFFSET + 0x24)
+#define AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3628		 (AUX_OFFSET + 0x28)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_MASK	 GENMASK(9, 0)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT 0
+#define AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE                                     \
+	(BIT(0) << AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT)
+
+#define MTK_DP_AUX_P0_362C		  (AUX_OFFSET + 0x2C)
+#define AUX_NO_LENGTH_AUX_TX_P0_MASK	  BIT(0)
+#define AUX_NO_LENGTH_AUX_TX_P0_SHIFT	  0
+#define AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK BIT(1)
+#define AUX_RESERVED_RW_0_AUX_TX_P0_MASK  GENMASK(15, 2)
+
+#define MTK_DP_AUX_P0_3630		     (AUX_OFFSET + 0x30)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_MASK  BIT(3)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_AUX_P0_3634			(AUX_OFFSET + 0x34)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK	GENMASK(15, 8)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3640			      (AUX_OFFSET + 0x40)
+#define AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK	      BIT(6)
+#define AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT  GENMASK(2, 1)
+#define AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT (BIT(0) | BIT(2))
+#define AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT BIT(2)
+#define AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT	      GENMASK(1, 0)
+#define AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(1)
+#define AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT	      0
+
+#define MTK_DP_AUX_P0_3644		   (AUX_OFFSET + 0x44)
+#define MCU_REQUEST_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3648		       (AUX_OFFSET + 0x48)
+#define MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_AUX_P0_364C		       (AUX_OFFSET + 0x4C)
+#define MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3650		      (AUX_OFFSET + 0x50)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_MASK	      GENMASK(15, 12)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT      GENMASK(3, 2)
+#define PHY_FIFO_RST_AUX_TX_P0_MASK	      BIT(9)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK  BIT(8)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3658	    (AUX_OFFSET + 0x58)
+#define AUX_TX_OV_EN_AUX_TX_P0_MASK BIT(0)
+
+#define MTK_DP_AUX_P0_3690		       (AUX_OFFSET + 0x90)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK  BIT(8)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3704				      (AUX_OFFSET + 0x104)
+#define AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK BIT(1)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK		      BIT(2)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT		      BIT(1)
+
+#define MTK_DP_AUX_P0_3708 (AUX_OFFSET + 0x108)
+
+#define MTK_DP_AUX_P0_37C8	    (AUX_OFFSET + 0x1C8)
+#define MTK_ATOP_EN_AUX_TX_P0_MASK  BIT(0)
+#define MTK_ATOP_EN_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_TOP_PWR_STATE	       (TOP_OFFSET + 0x0)
+#define DP_PWR_STATE_MASK	       GENMASK(1, 0)
+#define DP_PWR_STATE_BANDGAP	       BIT(0)
+#define DP_PWR_STATE_BANDGAP_TPLL      BIT(1)
+#define DP_PWR_STATE_BANDGAP_TPLL_LANE GENMASK(1, 0)
+
+#define MTK_DP_TOP_SWING_EMP	(TOP_OFFSET + 0x4)
+#define DP_TX0_VOLT_SWING_MASK	GENMASK(1, 0)
+#define DP_TX0_VOLT_SWING_SHIFT 0
+#define DP_TX0_PRE_EMPH_MASK	GENMASK(3, 2)
+#define DP_TX0_PRE_EMPH_SHIFT	BIT(1)
+#define DP_TX1_VOLT_SWING_MASK	GENMASK(9, 8)
+#define DP_TX1_VOLT_SWING_SHIFT BIT(3)
+#define DP_TX1_PRE_EMPH_MASK	GENMASK(11, 10)
+#define DP_TX2_VOLT_SWING_MASK	GENMASK(17, 16)
+#define DP_TX2_PRE_EMPH_MASK	GENMASK(19, 18)
+#define DP_TX3_VOLT_SWING_MASK	GENMASK(25, 24)
+#define DP_TX3_PRE_EMPH_MASK	GENMASK(27, 26)
+
+#define MTK_DP_TOP_RESET_AND_PROBE (TOP_OFFSET + 0x20)
+#define SW_RST_B_SHIFT		   0
+#define SW_RST_B_PHYD		   (BIT(4) << SW_RST_B_SHIFT)
+
+#define MTK_DP_TOP_IRQ_STATUS	   (TOP_OFFSET + 0x28)
+#define RGS_IRQ_STATUS_SHIFT	   0
+#define RGS_IRQ_STATUS_TRANSMITTER (BIT(1) << RGS_IRQ_STATUS_SHIFT)
+
+#define MTK_DP_TOP_IRQ_MASK  (TOP_OFFSET + 0x2C)
+#define IRQ_MASK_AUX_TOP_IRQ BIT(2)
+
+#define MTK_DP_TOP_MEM_PD (TOP_OFFSET + 0x38)
+#define MEM_ISO_EN_SHIFT  0
+#define FUSE_SEL_SHIFT	  BIT(1)
+
+#endif /*_MTK_DP_REG_H_*/
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index e25ac61aac08..4e378eb34071 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -906,6 +906,9 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+	&mtk_dp_driver,
+#endif
 	&mtk_drm_platform_driver,
 	&mtk_dsi_driver,
 	&mtk_ethdr_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 8d3ff32b5364..04de9436ea85 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -59,6 +59,9 @@ extern struct platform_driver mtk_disp_ovl_adaptor_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+extern struct platform_driver mtk_dp_driver;
+#endif
 extern struct platform_driver mtk_dsi_driver;
 extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

From: Markus Schneider-Pargmann <msp@baylibre.com>

This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.

It supports the mt8195, the embedded DisplayPort units. It offers
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 <jason-jh.lin@mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/Kconfig       |    8 +
 drivers/gpu/drm/mediatek/Makefile      |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2570 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  570 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |    3 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |    3 +
 6 files changed, 3156 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..a37b6ec9f01e 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -21,6 +21,14 @@ config DRM_MEDIATEK
 	  This driver provides kernel mode setting and
 	  buffer management to userspace.
 
+config DRM_MEDIATEK_DP
+	tristate "DRM DPTX Support for Mediatek SoCs"
+	depends on DRM_MEDIATEK
+	select PHY_MTK_DP
+	select DRM_DP_HELPER
+	help
+	  DRM/KMS Display Port driver for Mediatek SoCs.
+
 config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 3abd27d7c91d..d4d193f60271 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_DRM_MEDIATEK_DP) += 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 000000000000..8eb17ae82bfd
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +-2,2567 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/dp/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/hdmi-codec.h>
+#include <video/videomode.h>
+
+#include "mtk_dp_reg.h"
+
+#define MTK_VDOSYS1_MAX_FRAMERATE 60
+#define MTK_DP_4P1T 4
+#define MTK_DP_HDE 2
+#define MTK_DP_PIX_PER_ADDR 2
+#define MTK_DP_AUX_WAIT_REPLY_COUNT 20
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT 3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT 8
+#define MTK_DP_TRAIN_MAX_ITERATIONS 5
+
+#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_NORMAL,
+	MTK_DP_TRAIN_STATE_DPIDLE,
+};
+
+struct mtk_dp_timings {
+	struct videomode vm;
+
+	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;
+
+	u8  irq_status;
+	int check_cap_count;
+};
+
+/* 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,
+};
+
+//TODO: redundant with DP_MSA_MISC_*_BPC ?
+/* Same values as used for DP Spec MISC0 bits 5,6,7 */
+enum mtk_dp_color_depth {
+	MTK_DP_COLOR_DEPTH_6BIT = 0,
+	MTK_DP_COLOR_DEPTH_8BIT = 1,
+	MTK_DP_COLOR_DEPTH_10BIT = 2,
+	MTK_DP_COLOR_DEPTH_12BIT = 3,
+	MTK_DP_COLOR_DEPTH_16BIT = 4,
+	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
+};
+
+struct mtk_dp_info {
+	enum mtk_dp_color_depth depth;
+	enum dp_pixelformat format;
+	struct mtk_dp_timings timings;
+};
+
+struct dp_cal_data {
+	unsigned int glb_bias_trim;
+	unsigned int clktx_impse;
+
+	unsigned int *ln_tx_impsel_pmos;
+	unsigned int *ln_tx_impsel_nmos;
+};
+
+struct mtk_dp {
+	struct device *dev;
+	struct platform_device *phy_dev;
+	struct phy *phy;
+	struct dp_cal_data cal_data;
+	u8 max_lanes;
+	u8 max_linkrate;
+
+	struct drm_device *drm_dev;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_dp_aux aux;
+
+	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
+
+	struct mtk_dp_info info;
+	enum mtk_dp_state state;
+
+	struct mtk_dp_train_info train_info;
+	enum mtk_dp_train_state train_state;
+	unsigned int input_fmt;
+
+	struct regmap *regs;
+	struct clk *dp_tx_clk;
+
+	bool enabled;
+
+	bool has_fec;
+	/* Protects the mtk_dp struct */
+	struct mutex dp_lock;
+
+	struct drm_connector *conn;
+};
+
+static struct regmap_config mtk_dp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = SEC_OFFSET + 0x90,
+	.name = "mtk-dp-registers",
+};
+
+static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
+{
+	return container_of(b, struct mtk_dp, bridge);
+}
+
+static u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
+{
+	u32 read_val;
+	int ret;
+
+	ret = regmap_read(mtk_dp->regs, offset, &read_val);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to read register 0x%x: %d\n",
+			offset, ret);
+		return 0;
+	}
+
+	return read_val;
+}
+
+static int mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
+{
+	int ret;
+
+	ret = regmap_write(mtk_dp->regs, offset, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to write register 0x%x with value 0x%x: %d\n",
+			offset, val, ret);
+	return ret;
+}
+
+static int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset, u32 val,
+			      u32 mask)
+{
+	int ret;
+
+	ret = regmap_update_bits(mtk_dp->regs, offset, mask, val);
+	if (ret)
+		dev_err(mtk_dp->dev,
+			"Failed to update register 0x%x with value 0x%x, mask 0x%x: %d\n",
+			offset, val, mask, ret);
+	return ret;
+}
+
+static int mtk_dp_bulk_16bit_write(struct mtk_dp *mtk_dp, u32 offset, u8 *buf,
+				   size_t length)
+{
+	int i;
+	int ret = 0;
+	int num_regs = (length + 1) / 2;
+
+	/* 2 bytes per register */
+	for (i = 0; i < num_regs; i++) {
+		u32 val = buf[i * 2] |
+			  (i * 2 + 1 < length ? buf[i * 2 + 1] << 8 : 0);
+
+		ret = mtk_dp_write(mtk_dp, offset + i * 4, val);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static unsigned long mtk_dp_sip_atf_call(unsigned int cmd, unsigned int para)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32, cmd, para, 0, 0, 0, 0, 0,
+		      &res);
+
+	pr_debug("[DPTX]%s cmd 0x%x, p1 0x%x, ret 0x%lx-0x%lx", __func__, cmd,
+		 para, res.a0, res.a1);
+	return res.a1;
+}
+
+static int mtk_dp_msa_bypass_disable(struct mtk_dp *mtk_dp)
+{
+	const u16 bits_to_set =
+		BIT(HTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VTOTAL_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSTART_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HWIDTH_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VHEIGHT_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(HSP_SEL_DP_ENC0_P0_SHIFT) | BIT(HSW_SEL_DP_ENC0_P0_SHIFT) |
+		BIT(VSP_SEL_DP_ENC0_P0_SHIFT) | BIT(VSW_SEL_DP_ENC0_P0_SHIFT);
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3030, bits_to_set,
+			   bits_to_set);
+}
+
+static int mtk_dp_set_msa(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3010, mode.htotal,
+				 HTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3018,
+				 timings->vm.hsync_len + timings->vm.hback_porch,
+			   HSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028,
+				 timings->vm.hsync_len << HSW_SW_DP_ENC0_P0_SHIFT,
+			   HSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3028, 0,
+				 HSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3020, timings->vm.hactive,
+				 HWIDTH_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3014, mode.vtotal,
+				 VTOTAL_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_301C,
+				 timings->vm.vsync_len + timings->vm.vback_porch,
+			   VSTART_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C,
+				 timings->vm.vsync_len << VSW_SW_DP_ENC0_P0_SHIFT,
+			   VSW_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_302C, 0,
+				 VSP_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3024, timings->vm.vactive,
+				 VHEIGHT_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3064, timings->vm.hactive,
+				 HDE_NUM_LAST_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3154, mode.htotal,
+				 PGEN_HTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3158,
+				 timings->vm.hfront_porch,
+			   PGEN_HSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_315C, timings->vm.hsync_len,
+				 PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
+				 timings->vm.hback_porch + timings->vm.hsync_len,
+			   PGEN_HFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3164, timings->vm.hactive,
+				 PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3168, mode.vtotal,
+				 PGEN_VTOTAL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_316C,
+				 timings->vm.vfront_porch,
+			   PGEN_VSYNC_RISING_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3170, timings->vm.vsync_len,
+				 PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
+				 timings->vm.vback_porch + timings->vm.vsync_len,
+			   PGEN_VFDE_START_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3178, timings->vm.vactive,
+				 PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
+				   enum dp_pixelformat color_format)
+{
+	u32 val;
+	int ret;
+
+	mtk_dp->info.format = color_format;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_format << DP_TEST_COLOR_FORMAT_SHIFT,
+				 DP_TEST_COLOR_FORMAT_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_format) {
+	case DP_PIXELFORMAT_YUV422:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422;
+		break;
+	case DP_PIXELFORMAT_YUV420:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420;
+		break;
+	case DP_PIXELFORMAT_RGB:
+	case DP_PIXELFORMAT_YUV444:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
+		break;
+	case DP_PIXELFORMAT_Y_ONLY:
+	case DP_PIXELFORMAT_RAW:
+	case DP_PIXELFORMAT_RESERVED:
+	default:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
+			 color_format);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_color_depth(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_color_depth color_depth)
+{
+	int ret;
+	u32 val;
+
+	mtk_dp->info.depth = color_depth;
+
+	/* Update MISC0 */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+				 color_depth << DP_TEST_BIT_DEPTH_SHIFT,
+				 DP_TEST_BIT_DEPTH_MASK);
+
+	if (ret)
+		return ret;
+
+	switch (color_depth) {
+	case MTK_DP_COLOR_DEPTH_6BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_8BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_10BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_12BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_16BIT:
+		val = VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT;
+		break;
+	case MTK_DP_COLOR_DEPTH_UNKNOWN:
+		drm_warn(mtk_dp->drm_dev, "Unsupported color depth %d\n",
+			 color_depth);
+		return -EINVAL;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, val,
+				  VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_mn_overwrite_disable(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				  VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_set_sram_read_start(struct mtk_dp *mtk_dp, u32 val)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				  val << SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT,
+				  SRAM_START_READ_THRD_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_setup_encoder(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				 BIT(VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT),
+				 VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+				 0x20 << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 0x20 << SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT,
+			    SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3300,
+				 2 << VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT,
+			    VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
+				 4 << FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT,
+			    FIFO_READ_START_POINT_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368,
+			   1 << VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT |
+			   1 << VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT |
+			   BIT(SDP_DP13_EN_DP_ENC1_P0_SHIFT) |
+			   1 << BS2BS_MODE_DP_ENC1_P0_SHIFT);
+
+	return ret;
+}
+
+static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3038, 0,
+				 VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31B0,
+				 4 << PGEN_PATTERN_SEL_SHIFT, PGEN_PATTERN_SEL_MASK);
+
+	return ret;
+}
+
+static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
+{
+	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
+		  HPD_DB_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT) |
+		     BIT(AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT));
+	/* Wait for the irq to be cleared */
+	usleep_range(MTK_DP_AUX_WRITE_READ_WAIT_TIME_US,
+		     MTK_DP_AUX_WRITE_READ_WAIT_TIME_US * 2);
+}
+
+static int mtk_dp_aux_set_cmd(struct mtk_dp *mtk_dp, u8 cmd, u32 addr)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3644, cmd,
+				 MCU_REQUEST_COMMAND_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3648, addr,
+				 MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_364C, addr >> 16,
+				 MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_aux_cmd_complete(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+				  BIT(MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT),
+				  MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK |
+				  PHY_FIFO_RST_AUX_TX_P0_MASK |
+				  MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+}
+
+static int mtk_dp_aux_request_ready(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3630,
+				  BIT(AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT),
+				  AUX_TX_REQUEST_READY_AUX_TX_P0_MASK);
+}
+
+static void mtk_dp_aux_fill_write_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				       size_t length)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_AUX_P0_3708, buf, length);
+}
+
+static int mtk_dp_aux_read_rx_fifo(struct mtk_dp *mtk_dp, u8 *buf,
+				   size_t length, int read_delay)
+{
+	int ret;
+	int read_pos;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620, 0,
+				 AUX_RD_MODE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+
+	for (read_pos = 0; read_pos < length; read_pos++) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3620,
+					 BIT(AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT),
+					 AUX_RX_FIFO_READ_PULSE_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Hardware needs time to update the data */
+		usleep_range(read_delay, read_delay * 2);
+		buf[read_pos] =
+			(u8)(mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3620) &
+			     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK >>
+				     AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_set_length(struct mtk_dp *mtk_dp, size_t length)
+{
+	int ret;
+
+	if (length > 0) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3650,
+					 (length - 1)
+					 << MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT,
+					 MCU_REQ_DATA_NUM_AUX_TX_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C,
+					 BIT(AUX_NO_LENGTH_AUX_TX_P0_SHIFT),
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+	}
+
+	return ret;
+}
+
+static int mtk_dp_aux_wait_for_completion(struct mtk_dp *mtk_dp, bool is_read)
+{
+	int wait_reply = MTK_DP_AUX_WAIT_REPLY_COUNT;
+
+	while (--wait_reply) {
+		u32 aux_irq_status;
+
+		if (is_read) {
+			u32 fifo_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3618);
+
+			if (fifo_status &
+			    (AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK |
+			     AUX_RX_FIFO_FULL_AUX_TX_P0_MASK)) {
+				return 0;
+			}
+		}
+
+		aux_irq_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3640);
+		if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK)
+			return 0;
+
+		if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK)
+			return -ETIMEDOUT;
+
+		/* Give the hardware a chance to reach completion before retrying */
+		usleep_range(100, 500);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
+				  u32 addr, u8 *buf, size_t length)
+{
+	int ret;
+	u32 reply_cmd;
+
+	if (is_read && (length > DP_AUX_MAX_PAYLOAD_BYTES ||
+			(cmd == DP_AUX_NATIVE_READ && !length)))
+		return -EINVAL;
+
+	if (!is_read) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 BIT(AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT),
+					 AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	mtk_dp_aux_set_cmd(mtk_dp, cmd, addr);
+	mtk_dp_aux_set_length(mtk_dp, length);
+
+	if (!is_read) {
+		if (length)
+			mtk_dp_aux_fill_write_fifo(mtk_dp, buf, length);
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3704,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK,
+					 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+	}
+
+	mtk_dp_aux_request_ready(mtk_dp);
+
+	ret = mtk_dp_aux_wait_for_completion(mtk_dp, is_read);
+
+	reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
+		    AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
+
+	if (ret || reply_cmd) {
+		u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
+				 AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
+		if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) {
+			drm_err(mtk_dp->drm_dev,
+				"AUX Rx Aux hang, need SW reset\n");
+			return -EIO;
+		}
+
+		mtk_dp_aux_cmd_complete(mtk_dp);
+		mtk_dp_aux_irq_clear(mtk_dp);
+
+		return -ETIMEDOUT;
+	}
+
+	if (!length) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_362C, 0,
+					 AUX_NO_LENGTH_AUX_TX_P0_MASK |
+					 AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK |
+					 AUX_RESERVED_RW_0_AUX_TX_P0_MASK);
+
+		if (ret)
+			return ret;
+
+	} else if (is_read) {
+		int read_delay;
+
+		if (cmd == (DP_AUX_I2C_READ | DP_AUX_I2C_MOT) ||
+		    cmd == DP_AUX_I2C_READ)
+			read_delay = 500;
+		else
+			read_delay = 100;
+
+		mtk_dp_aux_read_rx_fifo(mtk_dp, buf, length, read_delay);
+	}
+
+	mtk_dp_aux_cmd_complete(mtk_dp);
+	mtk_dp_aux_irq_clear(mtk_dp);
+
+	return 0;
+}
+
+static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
+					  int swing_val, int preemphasis)
+{
+	int ret;
+
+	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
+
+	if (lane_num < 0 || lane_num > 3)
+		return false;
+
+	dev_dbg(mtk_dp->dev,
+		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
+		swing_val, preemphasis);
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 swing_val << (DP_TX0_VOLT_SWING_SHIFT + lane_shift),
+				 DP_TX0_VOLT_SWING_MASK << lane_shift);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
+				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT + lane_shift),
+				 DP_TX0_PRE_EMPH_MASK << lane_shift);
+
+	return !ret;
+}
+
+static int mtk_dp_reset_swing_pre_emphasis(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP, 0,
+				  DP_TX0_VOLT_SWING_MASK | DP_TX1_VOLT_SWING_MASK |
+				  DP_TX2_VOLT_SWING_MASK |
+				  DP_TX3_VOLT_SWING_MASK |
+				  DP_TX0_PRE_EMPH_MASK | DP_TX1_PRE_EMPH_MASK |
+				  DP_TX2_PRE_EMPH_MASK | DP_TX3_PRE_EMPH_MASK);
+}
+
+static int mtk_dp_fec_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				  enable ? BIT(FEC_EN_DP_TRANS_P0_SHIFT) : 0,
+				  FEC_EN_DP_TRANS_P0_MASK);
+}
+
+static u32 mtk_dp_swirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u32 irq_status = mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_35D0) &
+			 SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, irq_status,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, 0,
+					 SW_IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+			return ret;
+	}
+
+	return irq_status;
+}
+
+static u32 mtk_dp_hwirq_get_clear(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	u8 irq_status = (mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3418) &
+			 IRQ_STATUS_DP_TRANS_P0_MASK) >>
+			IRQ_STATUS_DP_TRANS_P0_SHIFT;
+
+	if (irq_status) {
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, irq_status,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, 0,
+					 IRQ_CLR_DP_TRANS_P0_MASK);
+		if (ret)
+		return ret;
+	}
+
+	return irq_status;
+}
+
+static int mtk_dp_hwirq_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = enable ? 0 : IRQ_MASK_DP_TRANS_P0_DISC_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_CONN_IRQ |
+		      IRQ_MASK_DP_TRANS_P0_INT_IRQ;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, val,
+			   IRQ_MASK_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_342C,
+				 XTAL_FREQ_DP_TRANS_P0_DEFAULT,
+			   XTAL_FREQ_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
+				 BIT(FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT),
+			   FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+				 BIT(AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT),
+			   AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_IRQ_MASK, IRQ_MASK_AUX_TOP_IRQ,
+				 IRQ_MASK_AUX_TOP_IRQ);
+
+	return ret;
+}
+
+static void mtk_dp_initialize_hpd_detect_settings(struct mtk_dp *mtk_dp)
+{
+	/* Debounce threshold */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   8 << HPD_DEB_THD_DP_TRANS_P0_SHIFT,
+			   HPD_DEB_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
+			    HPD_INT_THD_DP_TRANS_P0_UPPER_1100US)
+				   << HPD_INT_THD_DP_TRANS_P0_SHIFT,
+			   HPD_INT_THD_DP_TRANS_P0_MASK);
+
+	/* Connect threshold 1.5ms + 5 x 0.1ms = 2ms
+	 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+			   (5 << HPD_DISC_THD_DP_TRANS_P0_SHIFT) |
+				   (5 << HPD_CONN_THD_DP_TRANS_P0_SHIFT),
+			   HPD_DISC_THD_DP_TRANS_P0_MASK |
+				   HPD_CONN_THD_DP_TRANS_P0_MASK);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
+			   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	/* modify timeout threshold = 1595 [12 : 8] */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_360C, 0x1595,
+				 AUX_TIMEOUT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3658, 0,
+				 AUX_TX_OV_EN_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 25 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3634,
+				 25 << AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT,
+			   AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	/* 13 for 26M */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3614,
+				 13 << AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT,
+			   AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_37C8,
+				 BIT(MTK_ATOP_EN_AUX_TX_P0_SHIFT),
+			   MTK_ATOP_EN_AUX_TX_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
+				 VBID_VIDEO_MUTE_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	mtk_dp_set_color_format(mtk_dp, DP_PIXELFORMAT_RGB);
+	mtk_dp_set_color_depth(mtk_dp, MTK_DP_COLOR_DEPTH_8BIT);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3368,
+				 1 << BS2BS_MODE_DP_ENC1_P0_SHIFT,
+			   BS2BS_MODE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* dp tx encoder reset all sw */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
+				 BIT(DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT),
+			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				 DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_digital_sw_reset(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C,
+				 BIT(DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT),
+			   DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+	if (ret)
+		return ret;
+	/* Wait for sw reset to complete */
+	usleep_range(1000, 5000);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_340C, 0,
+				 DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_lanes(struct mtk_dp *mtk_dp, int lanes)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35F0,
+				 lanes == 0 ? 0 : BIT(3), BIT(3) | BIT(2));
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, lanes,
+				 LANE_NUM_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4,
+				 lanes << LANE_NUM_DP_TRANS_P0_SHIFT,
+			   LANE_NUM_DP_TRANS_P0_MASK);
+
+	return ret;
+}
+
+static int link_rate_to_mb_per_s(struct mtk_dp *mtk_dp,
+				 enum mtk_dp_linkrate linkrate)
+{
+	switch (linkrate) {
+	case MTK_DP_LINKRATE_RBR:
+		return 1620;
+	case MTK_DP_LINKRATE_HBR:
+		return 2700;
+	case MTK_DP_LINKRATE_HBR2:
+		return 5400;
+	case MTK_DP_LINKRATE_HBR3:
+		return 8100;
+	default:
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, unknown linkrate %d\n",
+			linkrate);
+		return -EINVAL;
+	}
+}
+
+static u32 check_cal_data_valid(struct mtk_dp *mtk_dp, u32 min, u32 max, u32 val, u32 default_val)
+{
+	if (val < min || val > max)
+		dev_warn(mtk_dp->dev, "Invalid calibration data: %d (< %d || > %d), returning default %d\n",
+			 val, min, max, default_val);
+		return default_val;
+
+	return val;
+}
+
+static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
+{
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+	struct device *dev = mtk_dp->dev;
+	struct nvmem_cell *cell;
+	u32 *buf;
+	size_t len;
+
+	cell = nvmem_cell_get(dev, "dp_calibration_data");
+	if (IS_ERR(cell)) {
+		dev_err(dev,
+			"Error: Failed to get nvmem cell dp_calibration_data\n");
+		return PTR_ERR(cell);
+	}
+
+	buf = (u32 *)nvmem_cell_read(cell, &len);
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) {
+		dev_err(dev,
+			"Error: Failed to read nvmem_cell_read fail len %ld\n",
+			(len / sizeof(u32)));
+		return PTR_ERR(buf);
+	}
+
+	cal_data->ln_tx_impsel_nmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_nmos)
+		return -ENOMEM;
+
+	cal_data->ln_tx_impsel_pmos = devm_kmalloc(mtk_dp->dev,
+						   mtk_dp->max_lanes * sizeof(unsigned int), GFP_KERNEL);
+	if (!cal_data->ln_tx_impsel_pmos)
+		return -ENOMEM;
+
+	cal_data->glb_bias_trim =
+		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+	cal_data->clktx_impse =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[0] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[1] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[2] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_pmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+	cal_data->ln_tx_impsel_nmos[3] =
+		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int mtk_dp_set_cal_data(struct mtk_dp *mtk_dp)
+{
+	int ret;
+	struct dp_cal_data *cal_data = &mtk_dp->cal_data;
+
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_DPAUX_TX,
+				 cal_data->clktx_impse << 20, RG_CKM_PT0_CKTX_IMPSEL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_GLB_BIAS_GEN_00,
+				 cal_data->glb_bias_trim << 16,
+			   RG_XTP_GLB_BIAS_INTR_CTRL);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_pmos[0] << 12,
+			   RG_XTP_LN0_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_0,
+				 cal_data->ln_tx_impsel_nmos[0] << 16,
+			   RG_XTP_LN0_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_pmos[1] << 12,
+			   RG_XTP_LN1_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_1,
+				 cal_data->ln_tx_impsel_nmos[1] << 16,
+			   RG_XTP_LN1_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_pmos[2] << 12,
+			   RG_XTP_LN2_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_2,
+				 cal_data->ln_tx_impsel_nmos[2] << 16,
+			   RG_XTP_LN2_TX_IMPSEL_NMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_pmos[3] << 12,
+			   RG_XTP_LN3_TX_IMPSEL_PMOS);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, DP_PHY_LANE_TX_3,
+				 cal_data->ln_tx_impsel_nmos[3] << 16,
+			   RG_XTP_LN3_TX_IMPSEL_NMOS);
+
+	return ret;
+}
+
+static int mtk_dp_phy_configure(struct mtk_dp *mtk_dp,
+				enum mtk_dp_linkrate link_rate, int lane_count)
+{
+	int ret;
+	union phy_configure_opts phy_opts = {
+		.dp = {
+			.link_rate = link_rate_to_mb_per_s(mtk_dp, link_rate),
+			.set_rate = 1,
+			.lanes = lane_count,
+			.set_lanes = 1,
+			.ssc = mtk_dp->train_info.sink_ssc,
+		}
+		};
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP,
+				 DP_PWR_STATE_MASK);
+	if (ret)
+		return ret;
+
+	ret = phy_configure(mtk_dp->phy, &phy_opts);
+
+	if (ret)
+		return ret;
+
+	mtk_dp_set_cal_data(mtk_dp);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_set_idle_pattern(struct mtk_dp *mtk_dp, bool enable)
+{
+	const u32 val = POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK |
+			POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK;
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3580, enable ? val : 0, val);
+}
+
+static int mtk_dp_train_set_pattern(struct mtk_dp *mtk_dp, int pattern)
+{
+	int ret;
+
+	if (pattern < 0 || pattern > 4) {
+		drm_err(mtk_dp->drm_dev,
+			"Implementation error, no such pattern %d\n", pattern);
+		return -EINVAL;
+	}
+
+	if (pattern == 1) { /* TPS1 */
+		ret = mtk_dp_set_idle_pattern(mtk_dp, false);
+		if (ret)
+			return ret;
+	}
+
+	return mtk_dp_update_bits(mtk_dp,
+			   MTK_DP_TRANS_P0_3400,
+			   pattern ? BIT(pattern - 1) << PATTERN1_EN_DP_TRANS_P0_SHIFT : 0,
+			   PATTERN1_EN_DP_TRANS_P0_MASK | PATTERN2_EN_DP_TRANS_P0_MASK |
+			   PATTERN3_EN_DP_TRANS_P0_MASK |
+			   PATTERN4_EN_DP_TRANS_P0_MASK);
+}
+
+static int mtk_dp_set_enhanced_frame_mode(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
+			   enable ? BIT(ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT) : 0,
+			   ENHANCED_FRAME_EN_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3404,
+			   enable ? DP_SCR_EN_DP_TRANS_P0_MASK : 0,
+			   DP_SCR_EN_DP_TRANS_P0_MASK);
+}
+
+static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+{
+	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
+
+	if (enable)
+		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
+			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+}
+
+static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, 0,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	/* Wait for power enable */
+	usleep_range(10, 200);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_RESET_AND_PROBE, SW_RST_B_PHYD,
+				 SW_RST_B_PHYD);
+	if (ret)
+		return ret;
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				 DP_PWR_STATE_BANDGAP_TPLL,
+			   DP_PWR_STATE_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
+			   DA_CKM_CKTX0_EN_FORCE_EN | DA_CKM_BIAS_LPF_EN_FORCE_VAL |
+		     DA_CKM_BIAS_EN_FORCE_VAL |
+		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
+		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
+
+	if (ret)
+		return ret;
+
+	/* Disable RX */
+	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
+
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
+			   0x550 | BIT(FUSE_SEL_SHIFT) | BIT(MEM_ISO_EN_SHIFT));
+
+	return ret;
+}
+
+static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
+{
+	mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR2;
+	mtk_dp->train_info.lane_count = mtk_dp->max_lanes;
+	mtk_dp->train_info.irq_status = 0;
+	mtk_dp->train_info.cable_plugged_in = false;
+	mtk_dp->train_info.cable_state_change = false;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	mtk_dp->state = MTK_DP_STATE_INITIAL;
+
+	mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+	mtk_dp->info.depth = MTK_DP_COLOR_DEPTH_8BIT;
+	memset(&mtk_dp->info.timings, 0, sizeof(struct mtk_dp_timings));
+	mtk_dp->info.timings.frame_rate = 60;
+
+	mtk_dp->has_fec = false;
+}
+
+static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
+{
+	u32 sram_read_start = MTK_DP_TBC_BUF_READ_START_ADDR;
+
+	if (mtk_dp->train_info.lane_count > 0) {
+		sram_read_start = min_t(u32,
+					MTK_DP_TBC_BUF_READ_START_ADDR,
+					mtk_dp->info.timings.vm.hactive /
+					mtk_dp->train_info.lane_count /
+					MTK_DP_4P1T / MTK_DP_HDE / MTK_DP_PIX_PER_ADDR);
+		mtk_dp_set_sram_read_start(mtk_dp, sram_read_start);
+	}
+
+	mtk_dp_setup_encoder(mtk_dp);
+}
+
+static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
+{
+	u8 target_frame_rate = 60;
+	u32 target_pixel_clk;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.frame_rate > 0) {
+		target_frame_rate = mtk_dp->info.timings.frame_rate;
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	} else if (mtk_dp->info.timings.pix_rate_khz > 0) {
+		target_pixel_clk = mtk_dp->info.timings.pix_rate_khz * 1000;
+	} else {
+		target_pixel_clk = mode.htotal *
+				   mode.vtotal *
+				   target_frame_rate;
+	}
+
+	mtk_dp->info.timings.pix_rate_khz = target_pixel_clk / 1000;
+}
+
+static void mtk_dp_set_tx_out(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_msa_bypass_disable(mtk_dp);
+	mtk_dp_calculate_pixrate(mtk_dp);
+	mtk_dp_pg_disable(mtk_dp);
+	mtk_dp_setup_tu(mtk_dp);
+}
+
+static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
+{
+	ssize_t ret;
+	u8 sink_count;
+	bool locked;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+	u32 sink_count_reg = DP_SINK_COUNT_ESI;
+	u32 link_status_reg = DP_LANE0_1_STATUS;
+
+	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg, &sink_count);
+	if (ret < 0) {
+		drm_err(mtk_dp->drm_dev, "Read sink count failed: %ld\n", ret);
+		return ret;
+	}
+
+	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg, link_status,
+			       sizeof(link_status));
+	if (!ret) {
+		drm_err(mtk_dp->drm_dev, "Read link status failed: %ld\n",
+			ret);
+		return ret;
+	}
+
+	locked = drm_dp_channel_eq_ok(link_status,
+				      mtk_dp->train_info.lane_count);
+	if (!locked && mtk_dp->train_state > MTK_DP_TRAIN_STATE_TRAINING_PRE)
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+
+	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR,
+				   DP_REMOTE_CONTROL_COMMAND_PENDING);
+
+	if (DP_GET_SINK_COUNT(sink_count) &&
+	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
+		mtk_dp->train_info.check_cap_count = 0;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+		msleep(20);
+	}
+
+	return 0;
+}
+
+static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
+					  u8 dpcd_adjust_req[2])
+{
+	int lane;
+
+	for (lane = 0; lane < lanes; ++lane) {
+		u8 val;
+		u8 swing;
+		u8 preemphasis;
+		int index = lane / 2;
+		int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
+
+		swing = (dpcd_adjust_req[index] >> shift) &
+			DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
+		preemphasis = ((dpcd_adjust_req[index] >> shift) &
+			       DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
+			      DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
+		val = swing << DP_TRAIN_VOLTAGE_SWING_SHIFT |
+		      preemphasis << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+		if (swing == DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
+			val |= DP_TRAIN_MAX_SWING_REACHED;
+		if (preemphasis == 3)
+			val |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+		mtk_dp_set_swing_pre_emphasis(mtk_dp, lane, swing, preemphasis);
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_LANE0_SET + lane,
+				   val);
+	}
+}
+
+static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
+				    u8 link_status[DP_LINK_STATUS_SIZE])
+{
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
+			 DP_LINK_STATUS_SIZE);
+}
+
+static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
+			      u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, false);
+	if (ret)
+		return ret;
+
+	if (*status_control == 0) {
+		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
+		if (ret)
+			return ret;
+
+		val = DP_LINK_SCRAMBLING_DISABLE |
+			DP_TRAINING_PATTERN_1;
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_1);
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 1;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
+					       mtk_dp->rx_cap);
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (drm_dp_clock_recovery_ok(link_status,
+				     target_lane_count)) {
+		mtk_dp->train_info.cr_done = true;
+		*iteration_count = 1;
+		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
+		return 0;
+	} else if (*prev_lane_adjust == link_status[4]) {
+		(*iteration_count)++;
+		if (*prev_lane_adjust & DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
+			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
+			return -EINVAL;
+		}
+	} else {
+		*prev_lane_adjust = link_status[4];
+	}
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8 target_linkrate,
+				u8 target_lane_count, int *iteration_count, u8 *lane_adjust,  int *status_control, u8 *prev_lane_adjust)
+{
+	int ret;
+	u8 val;
+	u8 link_status[DP_LINK_STATUS_SIZE] = {};
+
+	if (*status_control == 1) {
+		if (mtk_dp->train_info.tps4) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_TRAINING_PATTERN_4;
+		} else if (mtk_dp->train_info.tps3) {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_3;
+		} else {
+			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
+			if (ret)
+				return -EINVAL;
+
+			val = DP_LINK_SCRAMBLING_DISABLE |
+				DP_TRAINING_PATTERN_2;
+		}
+		drm_dp_dpcd_writeb(&mtk_dp->aux,
+				   DP_TRAINING_PATTERN_SET,
+				val);
+
+		drm_dp_dpcd_read(&mtk_dp->aux,
+				 DP_ADJUST_REQUEST_LANE0_1,
+				lane_adjust,
+				sizeof(*lane_adjust) * 2);
+
+		mtk_dp_train_update_swing_pre(mtk_dp,
+					      target_lane_count, lane_adjust);
+		*status_control = 2;
+		(*iteration_count)++;
+	}
+
+	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
+					   mtk_dp->rx_cap);
+
+	mtk_dp_read_link_status(mtk_dp, link_status);
+
+	if (!drm_dp_clock_recovery_ok(link_status,
+				      target_lane_count)) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
+		return -EINVAL;
+	}
+
+	if (drm_dp_channel_eq_ok(link_status,
+				 target_lane_count)) {
+		mtk_dp->train_info.eq_done = true;
+		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
+		return 0;
+	}
+
+	if (*prev_lane_adjust == link_status[4])
+		(*iteration_count)++;
+	else
+		*prev_lane_adjust = link_status[4];
+
+	return -EAGAIN;
+}
+
+static int mtk_dp_train_flow(struct mtk_dp *mtk_dp, u8 target_link_rate,
+			     u8 target_lane_count)
+{
+	u8 lane_adjust[2] = {};
+	bool pass_tps1 = false;
+	bool pass_tps2_3 = false;
+	int train_retries;
+	int status_control;
+	int iteration_count;
+	int ret;
+	u8 prev_lane_adjust;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LINK_BW_SET, target_link_rate);
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count | DP_LANE_COUNT_ENHANCED_FRAME_EN);
+
+	if (mtk_dp->train_info.sink_ssc)
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DOWNSPREAD_CTRL,
+				   DP_SPREAD_AMP_0_5);
+
+	train_retries = 0;
+	status_control = 0;
+	iteration_count = 1;
+	prev_lane_adjust = 0xFF;
+
+	mtk_dp_set_lanes(mtk_dp, target_lane_count / 2);
+	ret = mtk_dp_phy_configure(mtk_dp, target_link_rate, target_lane_count);
+	if (ret)
+		return -EINVAL;
+
+	dev_dbg(mtk_dp->dev,
+		"Link train target_link_rate = 0x%x, target_lane_count = 0x%x\n",
+		target_link_rate, target_lane_count);
+
+	do {
+		train_retries++;
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    ((mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) !=
+		     0x0)) {
+			return -ENODEV;
+		}
+
+		if (mtk_dp->train_state < MTK_DP_TRAIN_STATE_TRAINING)
+			return -EAGAIN;
+
+		if (!pass_tps1) {
+			ret = mtk_dp_train_tps_1(mtk_dp, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps1 = true;
+				train_retries = 0;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		} else {
+			ret = mtk_dp_train_tps_2_3(mtk_dp, target_link_rate, target_lane_count, &iteration_count, lane_adjust,  &status_control, &prev_lane_adjust);
+			if (!ret) {
+				pass_tps2_3 = true;
+				break;
+			} else if (ret == -EINVAL) {
+				break;
+			}
+		}
+
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_ADJUST_REQUEST_LANE0_1,
+				 lane_adjust, sizeof(lane_adjust));
+		mtk_dp_train_update_swing_pre(mtk_dp, target_lane_count,
+					      lane_adjust);
+	} while (train_retries < MTK_DP_TRAIN_RETRY_LIMIT &&
+		 iteration_count < MTK_DP_TRAIN_MAX_ITERATIONS);
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET,
+			   DP_TRAINING_PATTERN_DISABLE);
+	ret = mtk_dp_train_set_pattern(mtk_dp, 0);
+	if (ret)
+		return -EINVAL;
+
+	if (!pass_tps2_3)
+		return -ETIMEDOUT;
+
+	mtk_dp->train_info.link_rate = target_link_rate;
+	mtk_dp->train_info.lane_count = target_lane_count;
+
+	ret = mtk_dp_training_set_scramble(mtk_dp, true);
+	if (ret)
+		return ret;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET,
+			   target_lane_count |
+				   DP_LANE_COUNT_ENHANCED_FRAME_EN);
+	ret = mtk_dp_set_enhanced_frame_mode(mtk_dp, true);
+
+	return ret;
+}
+
+static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+{
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+	u8 val;
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	if (!mtk_dp_plug_state(mtk_dp))
+		return false;
+
+	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
+	/* Wait for power on */
+	usleep_range(2000, 5000);
+
+	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+
+	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap), sizeof(buf)));
+	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &= DP_TRAINING_AUX_RD_MASK;
+
+	train_info->link_rate =
+		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp->max_linkrate]);
+	train_info->lane_count =
+		min_t(int, mtk_dp->max_lanes, drm_dp_max_lane_count(buf));
+
+	train_info->tps3 = drm_dp_tps3_supported(buf);
+	train_info->tps4 = drm_dp_tps4_supported(buf);
+
+	train_info->sink_ssc =
+		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
+
+	train_info->sink_ssc = false;
+
+	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
+	if (val & DP_MST_CAP) {
+		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
+		drm_dp_dpcd_readb(&mtk_dp->aux,
+				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, &val);
+		if (val)
+			drm_dp_dpcd_writeb(&mtk_dp->aux,
+					   DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
+					   val);
+	}
+
+	return true;
+}
+
+static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
+{
+	phy_reset(mtk_dp->phy);
+	mtk_dp_reset_swing_pre_emphasis(mtk_dp);
+}
+
+static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+	u8 lane_count;
+	u8 link_rate;
+	u8 train_limit;
+	u8 max_link_rate;
+	u8 plug_wait;
+
+	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait > 0;
+	     --plug_wait)
+		/* Avoid short pulses on the HPD isr */
+		usleep_range(1000, 5000);
+	if (plug_wait == 0) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+		return -ENODEV;
+	}
+
+	link_rate = mtk_dp->rx_cap[1];
+	lane_count = mtk_dp->rx_cap[2] & 0x1F;
+
+	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate, link_rate);
+	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes, lane_count);
+	link_rate = mtk_dp->train_info.link_rate;
+	lane_count = mtk_dp->train_info.lane_count;
+
+	switch (link_rate) {
+	case MTK_DP_LINKRATE_RBR:
+	case MTK_DP_LINKRATE_HBR:
+	case MTK_DP_LINKRATE_HBR2:
+	case MTK_DP_LINKRATE_HBR25:
+	case MTK_DP_LINKRATE_HBR3:
+		break;
+	default:
+		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
+		break;
+	};
+
+	max_link_rate = link_rate;
+	for (train_limit = 6; train_limit > 0; train_limit--) {
+		mtk_dp->train_info.cr_done = false;
+		mtk_dp->train_info.eq_done = false;
+
+		mtk_dp_train_change_mode(mtk_dp);
+		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
+		if (ret)
+			return ret;
+
+		if (!mtk_dp->train_info.cr_done) {
+			switch (link_rate) {
+			case MTK_DP_LINKRATE_RBR:
+				lane_count = lane_count / 2;
+				link_rate = max_link_rate;
+				if (lane_count == 0) {
+					mtk_dp->train_state =
+						MTK_DP_TRAIN_STATE_DPIDLE;
+					return -EIO;
+				}
+				break;
+			case MTK_DP_LINKRATE_HBR:
+				link_rate = MTK_DP_LINKRATE_RBR;
+				break;
+			case MTK_DP_LINKRATE_HBR2:
+				link_rate = MTK_DP_LINKRATE_HBR;
+				break;
+			case MTK_DP_LINKRATE_HBR3:
+				link_rate = MTK_DP_LINKRATE_HBR2;
+				break;
+			default:
+				return -EINVAL;
+			};
+		} else if (!mtk_dp->train_info.eq_done) {
+			if (lane_count == 0)
+				return -EIO;
+
+			lane_count /= 2;
+		} else {
+			break;
+		}
+	}
+
+	if (train_limit == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+//TODO: check drm_dp_helpers for duplicated code
+
+static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
+{
+	if (enable) {
+		mtk_dp_set_tx_out(mtk_dp);
+		mtk_dp_video_mute(mtk_dp, false);
+	} else {
+		mtk_dp_video_mute(mtk_dp, true);
+	}
+}
+
+static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_mn_overwrite_disable(mtk_dp);
+
+	mtk_dp_set_msa(mtk_dp);
+
+	mtk_dp_set_color_depth(mtk_dp, mtk_dp->info.depth);
+	mtk_dp_set_color_format(mtk_dp, mtk_dp->info.format);
+}
+
+static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
+{
+	switch (mtk_dp->state) {
+	case MTK_DP_STATE_INITIAL:
+		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp->state = MTK_DP_STATE_IDLE;
+		break;
+
+	case MTK_DP_STATE_IDLE:
+		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
+			mtk_dp->state = MTK_DP_STATE_PREPARE;
+		break;
+
+	case MTK_DP_STATE_PREPARE:
+		mtk_dp_video_config(mtk_dp);
+		mtk_dp_video_enable(mtk_dp, true);
+
+		mtk_dp->state = MTK_DP_STATE_NORMAL;
+		break;
+
+	case MTK_DP_STATE_NORMAL:
+		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
+			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp->state = MTK_DP_STATE_IDLE;
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
+{
+	bool training_done = false;
+	short max_retry = 50;
+	int ret = 0;
+
+	do {
+		switch (mtk_dp->train_state) {
+		case MTK_DP_TRAIN_STATE_STARTUP:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKCAP:
+			if (mtk_dp_parse_capabilities(mtk_dp)) {
+				mtk_dp->train_info.check_cap_count = 0;
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
+			} else {
+				mtk_dp->train_info.check_cap_count++;
+
+				if (mtk_dp->train_info.check_cap_count >
+				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT) {
+					mtk_dp->train_info.check_cap_count = 0;
+					mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+					ret = -ETIMEDOUT;
+				}
+			}
+			break;
+
+		case MTK_DP_TRAIN_STATE_CHECKEDID:
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
+			mtk_dp_state_handler(mtk_dp);
+			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING;
+			break;
+
+		case MTK_DP_TRAIN_STATE_TRAINING:
+			ret = mtk_dp_train_start(mtk_dp);
+			if (ret == 0) {
+				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
+				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
+			} else if (ret != -EAGAIN) {
+				mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
+			}
+			break;
+		case MTK_DP_TRAIN_STATE_NORMAL:
+			mtk_dp_state_handler(mtk_dp);
+			training_done = true;
+			break;
+		case MTK_DP_TRAIN_STATE_DPIDLE:
+			break;
+		default:
+			break;
+		}
+
+		if (ret) {
+			if (ret == -EAGAIN)
+				continue;
+			/*
+			 * If we get any other error number, it doesn't
+			 * make any sense to keep iterating.
+			 */
+			break;
+		}
+	} while (!training_done || --max_retry);
+
+	return ret;
+}
+
+static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
+{
+	mtk_dp_set_idle_pattern(mtk_dp, true);
+	mtk_dp_initialize_priv_data(mtk_dp);
+
+	mtk_dp_initialize_settings(mtk_dp);
+	mtk_dp_initialize_aux_settings(mtk_dp);
+	mtk_dp_initialize_digital_settings(mtk_dp);
+	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690,
+			   BIT(RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT),
+			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK);
+	mtk_dp_initialize_hpd_detect_settings(mtk_dp);
+
+	mtk_dp_digital_sw_reset(mtk_dp);
+}
+
+static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	int event;
+	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
+
+	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected :
+						  connector_status_disconnected;
+
+	if (event < 0)
+		return IRQ_HANDLED;
+
+	if (mtk_dp->drm_dev) {
+		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
+		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
+	}
+
+	if (mtk_dp->train_info.cable_state_change) {
+		mtk_dp->train_info.cable_state_change = false;
+
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+		if (!mtk_dp->train_info.cable_plugged_in ||
+		    !mtk_dp_plug_state(mtk_dp)) {
+			mtk_dp_video_mute(mtk_dp, true);
+
+			mtk_dp_initialize_priv_data(mtk_dp);
+			mtk_dp_set_idle_pattern(mtk_dp, true);
+			if (mtk_dp->has_fec)
+				mtk_dp_fec_enable(mtk_dp, false);
+
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL,
+					   DP_PWR_STATE_MASK);
+		} else {
+			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+					   DP_PWR_STATE_BANDGAP_TPLL_LANE,
+					   DP_PWR_STATE_MASK);
+			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
+			mtk_dp->train_info.link_rate =
+				min_t(int, mtk_dp->max_linkrate,
+				      buf[mtk_dp->max_linkrate]);
+			mtk_dp->train_info.lane_count =
+				min_t(int, mtk_dp->max_lanes,
+				      drm_dp_max_lane_count(buf));
+		}
+	}
+
+	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
+		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
+		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
+		mtk_dp_hpd_sink_event(mtk_dp);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
+{
+	bool connected;
+	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
+	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
+	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
+
+	train_info->irq_status |= hwirq_status | swirq_status;
+
+	if (!train_info->irq_status)
+		return IRQ_HANDLED;
+
+	connected = mtk_dp_plug_state(mtk_dp);
+	if (connected || !train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+	else if (!connected || train_info->cable_plugged_in)
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;
+
+	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
+		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
+		train_info->cable_plugged_in = true;
+	} else {
+		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
+		train_info->cable_plugged_in = false;
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+	}
+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev)
+{
+	struct mtk_dp *mtk_dp = dev;
+	u32 irq_status;
+
+	irq_status = mtk_dp_read(mtk_dp, MTK_DP_TOP_IRQ_STATUS);
+
+	if (!irq_status)
+		return IRQ_HANDLED;
+
+	if (irq_status & RGS_IRQ_STATUS_TRANSMITTER)
+		return mtk_dp_hpd_isr_handler(mtk_dp);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
+			   struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	mtk_dp->regs = devm_regmap_init_mmio(dev, base, &mtk_dp_regmap_config);
+	if (IS_ERR(mtk_dp->regs))
+		return PTR_ERR(mtk_dp->regs);
+
+	mtk_dp->dp_tx_clk = devm_clk_get(dev, "faxi");
+	if (IS_ERR(mtk_dp->dp_tx_clk)) {
+		dev_err(dev, "Failed to get dptx clock: %d\n", ret);
+		mtk_dp->dp_tx_clk = NULL;
+		return PTR_ERR(mtk_dp->dp_tx_clk);
+	}
+
+	ret = device_property_read_u8(dev, "max-lanes", &mtk_dp->max_lanes);
+	if (ret)
+		return ret;
+
+	ret = device_property_read_u8(dev, "max-linkrate", &mtk_dp->max_linkrate);
+
+	return ret;
+}
+
+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 enabled = mtk_dp->enabled;
+	struct edid *new_edid = NULL;
+
+//TODO: refcount enabled so that we don't have any surprises...
+
+	if (!enabled)
+		drm_bridge_chain_pre_enable(bridge);
+
+	if (mtk_dp_plug_state(mtk_dp))
+		new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc);
+
+	if (!enabled)
+		drm_bridge_chain_post_disable(bridge);
+
+	return new_edid;
+}
+
+static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+				   struct drm_dp_aux_msg *msg)
+{
+	struct mtk_dp *mtk_dp;
+	bool is_read;
+	u8 request;
+	size_t accessed_bytes = 0;
+	int ret = 0;
+
+	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
+
+	if (!mtk_dp->train_info.cable_plugged_in ||
+	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
+		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
+		return -EAGAIN;
+	}
+
+	switch (msg->request) {
+	case DP_AUX_I2C_MOT:
+	case DP_AUX_I2C_WRITE:
+	case DP_AUX_NATIVE_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
+		request = msg->request & ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
+		is_read = false;
+		break;
+	case DP_AUX_I2C_READ:
+	case DP_AUX_NATIVE_READ:
+	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
+		request = msg->request;
+		is_read = true;
+		break;
+	default:
+		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
+			msg->request);
+		return -EINVAL;
+	}
+
+	if (msg->size == 0) {
+		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
+					     msg->address + accessed_bytes,
+					     msg->buffer + accessed_bytes, 0);
+	} else {
+		while (accessed_bytes < msg->size) {
+			size_t to_access =
+				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
+				      msg->size - accessed_bytes);
+
+			ret = mtk_dp_aux_do_transfer(mtk_dp,
+						     is_read, request,
+							 msg->address + accessed_bytes,
+							 msg->buffer + accessed_bytes,
+							 to_access);
+
+			if (ret) {
+				drm_info(mtk_dp->drm_dev,
+					 "Failed to do AUX transfer: %d\n", ret);
+				break;
+			}
+			accessed_bytes += to_access;
+		}
+	}
+
+	if (ret) {
+		msg->reply = DP_AUX_NATIVE_REPLY_NACK | DP_AUX_I2C_REPLY_NACK;
+		return ret;
+	}
+
+	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
+	return msg->size;
+}
+
+static void mtk_dp_poweroff(struct mtk_dp *mtk_dp)
+{
+	mutex_lock(&mtk_dp->dp_lock);
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+	mtk_dp_power_disable(mtk_dp);
+	phy_exit(mtk_dp->phy);
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+
+	mutex_unlock(&mtk_dp->dp_lock);
+}
+
+static int mtk_dp_poweron(struct mtk_dp *mtk_dp)
+{
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->dp_lock);
+
+	ret = clk_prepare_enable(mtk_dp->dp_tx_clk);
+	if (ret < 0) {
+		dev_err(mtk_dp->dev, "Fail to enable clock: %d\n", ret);
+		goto err;
+	}
+	ret = phy_init(mtk_dp->phy);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to initialize phy: %d\n", ret);
+		goto err_phy_init;
+	}
+	ret = mtk_dp_phy_configure(mtk_dp, MTK_DP_LINKRATE_RBR, 1);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to configure phy: %d\n", ret);
+		goto err_phy_config;
+	}
+
+	mtk_dp_init_port(mtk_dp);
+	ret = mtk_dp_power_enable(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+
+err_phy_config:
+	phy_exit(mtk_dp->phy);
+err_phy_init:
+	clk_disable_unprepare(mtk_dp->dp_tx_clk);
+err:
+	mutex_unlock(&mtk_dp->dp_lock);
+	return ret;
+}
+
+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;
+
+	ret = mtk_dp_poweron(mtk_dp);
+	if (ret)
+		return ret;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mtk_dp->dev, "Driver does not provide a connector!");
+		return -EINVAL;
+	}
+
+	if (mtk_dp->next_bridge) {
+		ret = drm_bridge_attach(bridge->encoder, mtk_dp->next_bridge,
+					&mtk_dp->bridge, flags);
+		if (ret) {
+			drm_warn(mtk_dp->drm_dev,
+				 "Failed to attach external bridge: %d\n", ret);
+			return ret;
+		}
+	}
+
+	mtk_dp->drm_dev = bridge->dev;
+
+	return 0;
+}
+
+static void mtk_dp_bridge_detach(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->drm_dev = NULL;
+}
+
+static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp->state = MTK_DP_STATE_IDLE;
+	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
+
+	mtk_dp->enabled = false;
+	/* Ensure the sink is muted before powering off */
+	msleep(100);
+	mtk_dp_poweroff(mtk_dp);
+}
+
+static void mtk_dp_parse_drm_mode_timings(struct mtk_dp *mtk_dp,
+					  struct drm_display_mode *mode)
+{
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_to_videomode(mode, &timings->vm);
+	timings->frame_rate = drm_mode_vrefresh(mode);
+}
+
+static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
+					struct drm_bridge_state *old_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+
+	mtk_dp->conn = drm_atomic_get_new_connector_for_encoder(old_state->base.state,
+								bridge->encoder);
+	if (!mtk_dp->conn) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector is missing\n");
+		return;
+	}
+
+	/* Training */
+	if (mtk_dp_train_handler(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev, "Training failed\n");
+		return;
+	}
+
+	mtk_dp->enabled = true;
+}
+
+static enum drm_mode_status
+mtk_dp_bridge_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+	u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24;
+
+	if (rx_linkrate * mtk_dp->train_info.lane_count < mode->clock * bpp / 8)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock > 600000)
+		return MODE_CLOCK_HIGH;
+
+	if ((mode->clock * 1000) / (mode->htotal * mode->vtotal) > MTK_VDOSYS1_MAX_FRAMERATE)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *output_fmts;
+
+	*num_output_fmts = 0;
+	output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL);
+	if (!output_fmts)
+		return NULL;
+	*num_output_fmts = 1;
+	output_fmts[0] = MEDIA_BUS_FMT_FIXED;
+	return output_fmts;
+}
+
+static const u32 mt8195_input_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_YUV8_1X24,
+	MEDIA_BUS_FMT_YUYV8_1X16,
+};
+
+static u32 *mtk_dp_bridge_atomic_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)
+{
+	u32 *input_fmts;
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+	struct drm_display_info *display_info =
+		&conn_state->connector->display_info;
+	u32 rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
+
+	*num_input_fmts = 0;
+
+	if (((rx_linkrate * mtk_dp->train_info.lane_count) <
+	     (mode->clock * 24 / 8)) &&
+	    ((rx_linkrate * mtk_dp->train_info.lane_count) >
+	     (mode->clock * 16 / 8)) &&
+	    (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+		input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+		*num_input_fmts = 1;
+		input_fmts[0] = MEDIA_BUS_FMT_YUYV8_1X16;
+	} else {
+		input_fmts = kcalloc(ARRAY_SIZE(mt8195_input_fmts), sizeof(*input_fmts),
+				     GFP_KERNEL);
+		if (!input_fmts)
+			return NULL;
+
+		*num_input_fmts = ARRAY_SIZE(mt8195_input_fmts);
+		memcpy(input_fmts, mt8195_input_fmts, sizeof(mt8195_input_fmts));
+	}
+
+	return input_fmts;
+}
+
+static int mtk_dp_bridge_atomic_check(struct drm_bridge *bridge,
+				      struct drm_bridge_state *bridge_state,
+				      struct drm_crtc_state *crtc_state,
+				      struct drm_connector_state *conn_state)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	struct drm_crtc *crtc = conn_state->crtc;
+	unsigned int input_bus_format;
+
+	input_bus_format = bridge_state->input_bus_cfg.format;
+
+	dev_dbg(mtk_dp->dev, "input format 0x%04x, output format 0x%04x\n",
+		bridge_state->input_bus_cfg.format,
+		 bridge_state->output_bus_cfg.format);
+
+	mtk_dp->input_fmt = input_bus_format;
+	if (mtk_dp->input_fmt == MEDIA_BUS_FMT_YUYV8_1X16)
+		mtk_dp->info.format = DP_PIXELFORMAT_YUV422;
+	else
+		mtk_dp->info.format = DP_PIXELFORMAT_RGB;
+
+	if (!crtc) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as connector state doesn't have a crtc\n");
+		return -EINVAL;
+	}
+
+	mtk_dp_parse_drm_mode_timings(mtk_dp, &crtc_state->adjusted_mode);
+	if (!mtk_dp_parse_capabilities(mtk_dp)) {
+		drm_err(mtk_dp->drm_dev,
+			"Can't enable bridge as nothing is plugged in\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
+	.atomic_check = mtk_dp_bridge_atomic_check,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_get_output_bus_fmts = mtk_dp_bridge_atomic_get_output_bus_fmts,
+	.atomic_get_input_bus_fmts = mtk_dp_bridge_atomic_get_input_bus_fmts,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.attach = mtk_dp_bridge_attach,
+	.detach = mtk_dp_bridge_detach,
+	.atomic_enable = mtk_dp_bridge_atomic_enable,
+	.atomic_disable = mtk_dp_bridge_atomic_disable,
+	.mode_valid = mtk_dp_bridge_mode_valid,
+	.get_edid = mtk_dp_get_edid,
+};
+
+static int mtk_dp_probe(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp;
+	struct device *dev = &pdev->dev;
+	int ret;
+	int irq_num = 0;
+
+	mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
+	if (!mtk_dp)
+		return -ENOMEM;
+
+	mtk_dp->dev = dev;
+
+	irq_num = platform_get_irq(pdev, 0);
+	if (irq_num < 0)
+		return dev_err_probe(dev, irq_num, "failed to request dp irq resource\n");
+
+	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+	if (IS_ERR(mtk_dp->next_bridge)) {
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
+	}
+
+	ret = mtk_dp_dt_parse(mtk_dp, pdev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to parse dt\n");
+
+	drm_dp_aux_init(&mtk_dp->aux);
+	mtk_dp->aux.name = "aux_mtk_dp";
+	mtk_dp->aux.transfer = mtk_dp_aux_transfer;
+
+	ret = devm_request_threaded_irq(dev, irq_num, mtk_dp_hpd_event,
+					mtk_dp_hpd_event_thread,
+					IRQ_TYPE_LEVEL_HIGH, dev_name(dev),
+					mtk_dp);
+	if (ret)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
+
+	mutex_init(&mtk_dp->dp_lock);
+
+	platform_set_drvdata(pdev, mtk_dp);
+
+	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
+							PLATFORM_DEVID_AUTO,
+							&mtk_dp->regs,
+							sizeof(struct regmap *));
+	if (IS_ERR(mtk_dp->phy_dev))
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev), "Failed to create device mediatek-dp-phy\n");
+
+	mtk_dp_get_calibration_data(mtk_dp);
+
+	mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
+
+	if (IS_ERR(mtk_dp->phy)) {
+		platform_device_unregister(mtk_dp->phy_dev);
+		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n");
+	}
+
+	mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
+	mtk_dp->bridge.of_node = dev->of_node;
+
+	mtk_dp->bridge.ops =
+		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
+	drm_bridge_add(&mtk_dp->bridge);
+	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_remove(struct platform_device *pdev)
+{
+	struct mtk_dp *mtk_dp = platform_get_drvdata(pdev);
+
+	platform_device_unregister(mtk_dp->phy_dev);
+	mtk_dp_video_mute(mtk_dp, true);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_dp_suspend(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
+		/* Ensure the sink is off before shutting down power */
+		usleep_range(2000, 3000);
+	}
+
+	ret = mtk_dp_power_disable(mtk_dp);
+	if (ret)
+		return ret;
+
+	mtk_dp_hwirq_enable(mtk_dp, false);
+
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+static int mtk_dp_resume(struct device *dev)
+{
+	int ret;
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+
+	mtk_dp_init_port(mtk_dp);
+	mtk_dp_hwirq_enable(mtk_dp, true);
+	ret = mtk_dp_power_enable(mtk_dp);
+
+	return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
+
+static const struct of_device_id mtk_dp_of_match[] = {
+	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{},
+};
+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 = &mtk_dp_pm_ops,
+	},
+};
+
+MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DisplayPort Driver");
+MODULE_LICENSE("GPL");
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 000000000000..848e5f697737
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
@@ -0,0 +1,570 @@
+/* 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                                             \
+	(BIT(0) | BIT(1) | BIT(5) | BIT(8) | BIT(10) | BIT(25) | BIT(31))
+#define MTK_DP_SIP_ATF_VIDEO_UNMUTE	BIT(5)
+#define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE (BIT(0) | BIT(5))
+
+#define DP_PHY_GLB_BIAS_GEN_00	  0
+#define RG_XTP_GLB_BIAS_INTR_CTRL GENMASK(20, 16)
+
+#define DP_PHY_GLB_DPAUX_TX    BIT(3)
+#define RG_CKM_PT0_CKTX_IMPSEL GENMASK(23, 20)
+
+#define DP_PHY_LANE_TX_0	  (BIT(2) | BIT(8))
+#define RG_XTP_LN0_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN0_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_1	  (BIT(2) | BIT(9))
+#define RG_XTP_LN1_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN1_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_2	  (BIT(2) | BIT(8) | BIT(9))
+#define RG_XTP_LN2_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN2_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define DP_PHY_LANE_TX_3	  (BIT(2) | BIT(10))
+#define RG_XTP_LN3_TX_IMPSEL_PMOS GENMASK(15, 12)
+#define RG_XTP_LN3_TX_IMPSEL_NMOS GENMASK(19, 16)
+
+#define TOP_OFFSET   BIT(13)
+#define ENC0_OFFSET  GENMASK(13, 12)
+#define ENC1_OFFSET  (BIT(9) | BIT(12) | BIT(13))
+#define TRANS_OFFSET (BIT(10) | BIT(12) | BIT(13))
+#define AUX_OFFSET   (BIT(9) | BIT(10) | BIT(12) | BIT(13))
+#define SEC_OFFSET   BIT(14)
+
+#define MTK_DP_HPD_DISCONNECT BIT(1)
+#define MTK_DP_HPD_CONNECT    BIT(2)
+#define MTK_DP_HPD_INTERRUPT  BIT(3)
+
+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
+#define DA_XTP_GLB_CKDET_EN_FORCE_VAL BIT(15)
+#define DA_XTP_GLB_CKDET_EN_FORCE_EN  BIT(14)
+#define DA_CKM_INTCKTX_EN_FORCE_VAL   BIT(13)
+#define DA_CKM_INTCKTX_EN_FORCE_EN    BIT(12)
+#define DA_CKM_CKTX0_EN_FORCE_VAL     BIT(11)
+#define DA_CKM_CKTX0_EN_FORCE_EN      BIT(10)
+#define DA_CKM_XTAL_CK_FORCE_VAL      BIT(9)
+#define DA_CKM_XTAL_CK_FORCE_EN	      BIT(8)
+#define DA_CKM_BIAS_LPF_EN_FORCE_VAL  BIT(7)
+#define DA_CKM_BIAS_LPF_EN_FORCE_EN   BIT(6)
+#define DA_CKM_BIAS_EN_FORCE_VAL      BIT(5)
+#define DA_CKM_BIAS_EN_FORCE_EN	      BIT(4)
+#define DA_XTP_GLB_AVD10_ON_FORCE_VAL BIT(3)
+#define DA_XTP_GLB_AVD10_ON_FORCE     BIT(2)
+#define DA_XTP_GLB_LDO_EN_FORCE_VAL   BIT(1)
+#define DA_XTP_GLB_LDO_EN_FORCE_EN    BIT(0)
+
+#define MTK_DP_1040		      (BIT(6) | BIT(12))
+#define RG_DPAUX_RX_VALID_DEGLITCH_EN BIT(2)
+#define RG_XTP_GLB_CKDET_EN	      BIT(1)
+#define RG_DPAUX_RX_EN		      BIT(0)
+
+#define MTK_DP_ENC0_P0_3000		   (ENC0_OFFSET + 0x00)
+#define LANE_NUM_DP_ENC0_P0_MASK	   GENMASK(1, 0)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_MASK	   BIT(2)
+#define VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT	   BIT(1)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_MASK	   BIT(3)
+#define VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT	   GENMASK(1, 0)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_MASK  BIT(4)
+#define ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT BIT(2)
+
+#define MTK_DP_ENC0_P0_3004			   (ENC0_OFFSET + 0x04)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK	   BIT(8)
+#define VIDEO_M_CODE_SEL_DP_ENC0_P0_SHIFT	   BIT(3)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_MASK  BIT(9)
+#define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0_SHIFT (BIT(0) | BIT(3))
+
+#define MTK_DP_ENC0_P0_3008		  (ENC0_OFFSET + 0x08)
+#define VIDEO_M_CODE_SW_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_300C		  (ENC0_OFFSET + 0x0C)
+#define VIDEO_M_CODE_SW_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3010	  (ENC0_OFFSET + 0x10)
+#define HTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3014	  (ENC0_OFFSET + 0x14)
+#define VTOTAL_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3018	  (ENC0_OFFSET + 0x18)
+#define HSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_301C	  (ENC0_OFFSET + 0x1C)
+#define VSTART_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3020	  (ENC0_OFFSET + 0x20)
+#define HWIDTH_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3024	   (ENC0_OFFSET + 0x24)
+#define VHEIGHT_SW_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3028	(ENC0_OFFSET + 0x28)
+#define HSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define HSW_SW_DP_ENC0_P0_SHIFT 0
+#define HSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_302C	(ENC0_OFFSET + 0x2C)
+#define VSW_SW_DP_ENC0_P0_MASK	GENMASK(14, 0)
+#define VSW_SW_DP_ENC0_P0_SHIFT 0
+#define VSP_SW_DP_ENC0_P0_MASK	(BIT(15))
+
+#define MTK_DP_ENC0_P0_3030			 (ENC0_OFFSET + 0x30)
+#define HTOTAL_SEL_DP_ENC0_P0_SHIFT		 0
+#define VTOTAL_SEL_DP_ENC0_P0_SHIFT		 BIT(0)
+#define HSTART_SEL_DP_ENC0_P0_SHIFT		 BIT(1)
+#define VSTART_SEL_DP_ENC0_P0_SHIFT		 GENMASK(1, 0)
+#define HWIDTH_SEL_DP_ENC0_P0_SHIFT		 BIT(2)
+#define VHEIGHT_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(2))
+#define HSP_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 1)
+#define HSW_SEL_DP_ENC0_P0_SHIFT		 GENMASK(2, 0)
+#define VSP_SEL_DP_ENC0_P0_SHIFT		 BIT(3)
+#define VSW_SEL_DP_ENC0_P0_SHIFT		 (BIT(0) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK	 (BIT(11))
+#define VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT	 (BIT(0) | BIT(1) | BIT(3))
+#define VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK (BIT(12))
+#define VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT	 GENMASK(3, 2)
+
+#define MTK_DP_ENC0_P0_3034 (ENC0_OFFSET + 0x34)
+
+#define MTK_DP_ENC0_P0_3038		  (ENC0_OFFSET + 0x38)
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK  (BIT(11))
+#define VIDEO_SOURCE_SEL_DP_ENC0_P0_SHIFT (BIT(0) | BIT(1) | BIT(3))
+
+#define MTK_DP_ENC0_P0_303C		      (ENC0_OFFSET + 0x3C)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_SHIFT 0
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK     GENMASK(10, 8)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT    BIT(3)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT                                     \
+	(0 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT                                     \
+	(1 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_10BIT                                     \
+	(2 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_8BIT                                      \
+	(3 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define VIDEO_COLOR_DEPTH_DP_ENC0_P0_6BIT                                      \
+	(4 << VIDEO_COLOR_DEPTH_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK  GENMASK(14, 12)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT GENMASK(3, 2)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB                                     \
+	(0 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422                                \
+	(1 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420                                \
+	(2 << PIXEL_ENCODE_FORMAT_DP_ENC0_P0_SHIFT)
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_MASK	 (BIT(15))
+#define VIDEO_MN_GEN_EN_DP_ENC0_P0_SHIFT GENMASK(3, 0)
+
+#define MTK_DP_ENC0_P0_3040		   (ENC0_OFFSET + 0x40)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_3044	       (ENC0_OFFSET + 0x44)
+#define VIDEO_N_CODE_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3048	       (ENC0_OFFSET + 0x48)
+#define VIDEO_N_CODE_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_304C		      (ENC0_OFFSET + 0x4C)
+#define VBID_VIDEO_MUTE_DP_ENC0_P0_MASK	      BIT(2)
+#define SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK BIT(8)
+
+#define MTK_DP_ENC0_P0_3050		      (ENC0_OFFSET + 0x50)
+#define VIDEO_N_CODE_MN_GEN_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3054		      (ENC0_OFFSET + 0x54)
+#define VIDEO_N_CODE_MN_GEN_1_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_3064	     (ENC0_OFFSET + 0x64)
+#define HDE_NUM_LAST_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3088	      (ENC0_OFFSET + 0x88)
+#define AU_EN_DP_ENC0_P0_MASK	      BIT(6)
+#define AU_EN_DP_ENC0_P0_SHIFT	      GENMASK(2, 1)
+#define AUDIO_8CH_EN_DP_ENC0_P0_MASK  BIT(7)
+#define AUDIO_8CH_SEL_DP_ENC0_P0_MASK BIT(8)
+#define AUDIO_2CH_EN_DP_ENC0_P0_MASK  (BIT(14))
+#define AUDIO_2CH_SEL_DP_ENC0_P0_MASK (BIT(15))
+
+#define MTK_DP_ENC0_P0_308C	    (ENC0_OFFSET + 0x8C)
+#define CH_STATUS_0_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3090	    (ENC0_OFFSET + 0x90)
+#define CH_STATUS_1_DP_ENC0_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_ENC0_P0_3094	    (ENC0_OFFSET + 0x94)
+#define CH_STATUS_2_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A0 (ENC0_OFFSET + 0xA0)
+
+#define MTK_DP_ENC0_P0_30A4	  (ENC0_OFFSET + 0xA4)
+#define AU_TS_CFG_DP_ENC0_P0_MASK GENMASK(7, 0)
+
+#define MTK_DP_ENC0_P0_30A8 (ENC0_OFFSET + 0xA8)
+
+#define MTK_DP_ENC0_P0_30AC (ENC0_OFFSET + 0xAC)
+
+#define MTK_DP_ENC0_P0_30B0 (ENC0_OFFSET + 0xB0)
+
+#define MTK_DP_ENC0_P0_30B4	  (ENC0_OFFSET + 0xB4)
+#define ISRC_CFG_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define ISRC_CFG_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_30B8 (ENC0_OFFSET + 0xB8)
+
+#define MTK_DP_ENC0_P0_30BC			   (ENC0_OFFSET + 0xBC)
+#define ISRC_CONT_DP_ENC0_P0_MASK		   BIT(0)
+#define ISRC_CONT_DP_ENC0_P0_SHIFT		   0
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK  GENMASK(10, 8)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT BIT(3)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_2                             \
+	(1 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_4                             \
+	(2 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MUL_8                             \
+	(3 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2                             \
+	(5 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_4                             \
+	(6 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+#define AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_8                             \
+	(7 << AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_SHIFT)
+
+#define MTK_DP_ENC0_P0_30D8 (ENC0_OFFSET + 0xD8)
+
+#define MTK_DP_ENC0_P0_312C	 (ENC0_OFFSET + 0x12C)
+#define ASP_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define ASP_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define ASP_HB3_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_3130 (ENC0_OFFSET + 0x130)
+
+#define MTK_DP_ENC0_P0_3138 (ENC0_OFFSET + 0x138)
+
+#define MTK_DP_ENC0_P0_3154	    (ENC0_OFFSET + 0x154)
+#define PGEN_HTOTAL_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3158		  (ENC0_OFFSET + 0x158)
+#define PGEN_HSYNC_RISING_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_315C		       (ENC0_OFFSET + 0x15C)
+#define PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3160		(ENC0_OFFSET + 0x160)
+#define PGEN_HFDE_START_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3164		       (ENC0_OFFSET + 0x164)
+#define PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(13, 0)
+
+#define MTK_DP_ENC0_P0_3168	    (ENC0_OFFSET + 0x168)
+#define PGEN_VTOTAL_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_316C		  (ENC0_OFFSET + 0x16C)
+#define PGEN_VSYNC_RISING_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3170		       (ENC0_OFFSET + 0x170)
+#define PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3174		(ENC0_OFFSET + 0x174)
+#define PGEN_VFDE_START_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_3178		       (ENC0_OFFSET + 0x178)
+#define PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_ENC0_P0_31B0    (ENC0_OFFSET + 0x1B0)
+#define PGEN_PATTERN_SEL_SHIFT BIT(2)
+#define PGEN_PATTERN_SEL_MASK  GENMASK(6, 4)
+
+#define MTK_DP_ENC0_P0_31C8		  (ENC0_OFFSET + 0x1C8)
+#define VSC_EXT_VESA_HB0_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_MASK  GENMASK(15, 8)
+#define VSC_EXT_VESA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31CC		  (ENC0_OFFSET + 0x1CC)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define VSC_EXT_VESA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_VESA_HB3_DP_ENC0_P0_MASK  GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D0		 (ENC0_OFFSET + 0x1D0)
+#define VSC_EXT_CEA_HB0_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+#define VSC_EXT_CEA_HB1_DP_ENC0_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC0_P0_31D4		 (ENC0_OFFSET + 0x1D4)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_MASK	 GENMASK(7, 0)
+#define VSC_EXT_CEA_HB2_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_HB3_DP_ENC0_P0_MASK	 GENMASK(15, 8)
+
+#define MTK_DP_ENC0_P0_31D8		  (ENC0_OFFSET + 0x1D8)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_MASK  GENMASK(5, 0)
+#define VSC_EXT_VESA_NUM_DP_ENC0_P0_SHIFT 0
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_MASK	  GENMASK(13, 8)
+#define VSC_EXT_CEA_NUM_DP_ENC0_P0_SHIFT  BIT(3)
+
+#define MTK_DP_ENC0_P0_31DC	  (ENC0_OFFSET + 0x1DC)
+#define HDR0_CFG_DP_ENC0_P0_MASK  GENMASK(7, 0)
+#define HDR0_CFG_DP_ENC0_P0_SHIFT 0
+
+#define MTK_DP_ENC0_P0_31E8 (ENC0_OFFSET + 0x1E8)
+
+#define MTK_DP_ENC0_P0_31EC		  (ENC0_OFFSET + 0x1EC)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK  BIT(4)
+#define AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT BIT(2)
+#define ISRC1_HB3_DP_ENC0_P0_MASK	  GENMASK(15, 8)
+#define ISRC1_HB3_DP_ENC0_P0_SHIFT	  BIT(3)
+
+#define MTK_DP_ENC1_P0_3200 (ENC1_OFFSET + 0x00)
+
+#define MTK_DP_ENC1_P0_3280		(ENC1_OFFSET + 0x80)
+#define SDP_PACKET_TYPE_DP_ENC1_P0_MASK GENMASK(4, 0)
+#define SDP_PACKET_W_DP_ENC1_P0		BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_MASK	BIT(5)
+#define SDP_PACKET_W_DP_ENC1_P0_SHIFT	(BIT(0) | BIT(2))
+
+#define MTK_DP_ENC1_P0_328C (ENC1_OFFSET + 0x8C)
+
+#define MTK_DP_ENC1_P0_3290 (ENC1_OFFSET + 0x90)
+
+#define MTK_DP_ENC1_P0_32A0 (ENC1_OFFSET + 0xA0)
+
+#define MTK_DP_ENC1_P0_32A4 (ENC1_OFFSET + 0xA4)
+
+#define MTK_DP_ENC1_P0_3300		     (ENC1_OFFSET + 0x100)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_SHIFT BIT(3)
+
+#define MTK_DP_ENC1_P0_3304			  (ENC1_OFFSET + 0x104)
+#define AU_PRTY_REGEN_DP_ENC1_P0_MASK		  BIT(8)
+#define AU_CH_STS_REGEN_DP_ENC1_P0_MASK		  BIT(9)
+#define AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK (BIT(12))
+
+#define MTK_DP_ENC1_P0_3324		  (ENC1_OFFSET + 0x124)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK  GENMASK(9, 8)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT BIT(3)
+#define AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX                                       \
+	(0 << AUDIO_SOURCE_MUX_DP_ENC1_P0_SHIFT)
+
+#define MTK_DP_ENC1_P0_3364			     (ENC1_OFFSET + 0x164)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK  GENMASK(11, 0)
+#define SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_SHIFT 0
+#define FIFO_READ_START_POINT_DP_ENC1_P0_MASK	     GENMASK(15, 12)
+#define FIFO_READ_START_POINT_DP_ENC1_P0_SHIFT	     GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_3368			       (ENC1_OFFSET + 0x168)
+#define VIDEO_SRAM_FIFO_CNT_RESET_SEL_DP_ENC1_P0_SHIFT 0
+#define VIDEO_STABLE_CNT_THRD_DP_ENC1_P0_SHIFT	       BIT(2)
+#define SDP_DP13_EN_DP_ENC1_P0_SHIFT		       BIT(3)
+#define BS2BS_MODE_DP_ENC1_P0_MASK		       GENMASK(13, 12)
+#define BS2BS_MODE_DP_ENC1_P0_SHIFT		       GENMASK(3, 2)
+
+#define MTK_DP_ENC1_P0_33F4 (ENC1_OFFSET + 0x1F4)
+
+#define MTK_DP_TRANS_P0_3400	      (TRANS_OFFSET + 0)
+#define PATTERN1_EN_DP_TRANS_P0_MASK  BIT(12)
+#define PATTERN1_EN_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+#define PATTERN2_EN_DP_TRANS_P0_MASK  BIT(13)
+#define PATTERN3_EN_DP_TRANS_P0_MASK  BIT(14)
+#define PATTERN4_EN_DP_TRANS_P0_MASK  BIT(15)
+
+#define MTK_DP_TRANS_P0_3404	   (TRANS_OFFSET + 0x4)
+#define DP_SCR_EN_DP_TRANS_P0_MASK BIT(0)
+
+#define MTK_DP_TRANS_P0_340C			       (TRANS_OFFSET + 0xC)
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_MASK (BIT(13))
+#define DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0_SHIFT                        \
+	(BIT(0) | BIT(2) | BIT(3))
+
+#define MTK_DP_TRANS_P0_3410		    (TRANS_OFFSET + 0x10)
+#define HPD_DEB_THD_DP_TRANS_P0_MASK	    GENMASK(3, 0)
+#define HPD_DEB_THD_DP_TRANS_P0_SHIFT	    0
+#define HPD_INT_THD_DP_TRANS_P0_MASK	    GENMASK(7, 4)
+#define HPD_INT_THD_DP_TRANS_P0_SHIFT	    BIT(2)
+#define HPD_INT_THD_DP_TRANS_P0_LOWER_500US (2 << HPD_INT_THD_DP_TRANS_P0_SHIFT)
+#define HPD_INT_THD_DP_TRANS_P0_UPPER_1100US                                   \
+	(2 << (HPD_INT_THD_DP_TRANS_P0_SHIFT + 2))
+#define HPD_DISC_THD_DP_TRANS_P0_MASK  GENMASK(11, 8)
+#define HPD_DISC_THD_DP_TRANS_P0_SHIFT BIT(3)
+#define HPD_CONN_THD_DP_TRANS_P0_MASK  GENMASK(15, 12)
+#define HPD_CONN_THD_DP_TRANS_P0_SHIFT GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_3414	(TRANS_OFFSET + 0x14)
+#define HPD_DB_DP_TRANS_P0_MASK BIT(2)
+
+#define MTK_DP_TRANS_P0_3418	      (TRANS_OFFSET + 0x18)
+#define IRQ_CLR_DP_TRANS_P0_MASK      GENMASK(3, 0)
+#define IRQ_MASK_DP_TRANS_P0_MASK     GENMASK(7, 4)
+#define IRQ_MASK_DP_TRANS_P0_SHIFT    BIT(2)
+#define IRQ_MASK_DP_TRANS_P0_DISC_IRQ (BIT(1) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_CONN_IRQ (BIT(2) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_MASK_DP_TRANS_P0_INT_IRQ  (BIT(3) << IRQ_MASK_DP_TRANS_P0_SHIFT)
+#define IRQ_STATUS_DP_TRANS_P0_MASK   GENMASK(15, 12)
+#define IRQ_STATUS_DP_TRANS_P0_SHIFT  GENMASK(3, 2)
+
+#define MTK_DP_TRANS_P0_342C	      (TRANS_OFFSET + 0x2C)
+#define XTAL_FREQ_DP_TRANS_P0_DEFAULT (BIT(0) | BIT(3) | BIT(5) | BIT(6))
+#define XTAL_FREQ_DP_TRANS_P0_MASK    GENMASK(7, 0)
+
+#define MTK_DP_TRANS_P0_3430			   (TRANS_OFFSET + 0x30)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_MASK	   GENMASK(1, 0)
+#define HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT BIT(1)
+
+#define MTK_DP_TRANS_P0_34A4	   (TRANS_OFFSET + 0xA4)
+#define LANE_NUM_DP_TRANS_P0_MASK  GENMASK(3, 2)
+#define LANE_NUM_DP_TRANS_P0_SHIFT BIT(1)
+
+#define MTK_DP_TRANS_P0_3540		    (TRANS_OFFSET + 0x140)
+#define FEC_EN_DP_TRANS_P0_MASK		    BIT(0)
+#define FEC_EN_DP_TRANS_P0_SHIFT	    0
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK  BIT(3)
+#define FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_TRANS_P0_3580			 (TRANS_OFFSET + 0x180)
+#define POST_MISC_DATA_LANE0_OV_DP_TRANS_P0_MASK BIT(8)
+#define POST_MISC_DATA_LANE1_OV_DP_TRANS_P0_MASK BIT(9)
+#define POST_MISC_DATA_LANE2_OV_DP_TRANS_P0_MASK (BIT(10))
+#define POST_MISC_DATA_LANE3_OV_DP_TRANS_P0_MASK (BIT(11))
+
+#define MTK_DP_TRANS_P0_35C4	     (TRANS_OFFSET + 0x1C4)
+#define SW_IRQ_MASK_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35C8	    (TRANS_OFFSET + 0x1C8)
+#define SW_IRQ_CLR_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define SW_IRQ_STATUS_DP_TRANS_P0_MASK	GENMASK(15, 0)
+#define SW_IRQ_STATUS_DP_TRANS_P0_SHIFT 0
+
+#define MTK_DP_TRANS_P0_35D0		     (TRANS_OFFSET + 0x1D0)
+#define SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_TRANS_P0_35F0 (TRANS_OFFSET + 0x1F0)
+
+#define MTK_DP_AUX_P0_360C	       (AUX_OFFSET + 0xC)
+#define AUX_TIMEOUT_THR_AUX_TX_P0_MASK GENMASK(12, 0)
+
+#define MTK_DP_AUX_P0_3614		  (AUX_OFFSET + 0x14)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK  GENMASK(6, 0)
+#define AUX_RX_UI_CNT_THR_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3618			 (AUX_OFFSET + 0x18)
+#define AUX_RX_FIFO_FULL_AUX_TX_P0_MASK		 BIT(9)
+#define AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3620		      (AUX_OFFSET + 0x20)
+#define AUX_RD_MODE_AUX_TX_P0_MASK	      BIT(9)
+#define AUX_RX_FIFO_READ_PULSE_TX_P0_MASK     BIT(8)
+#define AUX_RX_FIFO_R_PULSE_TX_P0_SHIFT	      BIT(3)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_MASK  GENMASK(7, 0)
+#define AUX_RX_FIFO_READ_DATA_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_AUX_P0_3624		    (AUX_OFFSET + 0x24)
+#define AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3628		 (AUX_OFFSET + 0x28)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_MASK	 GENMASK(9, 0)
+#define AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT 0
+#define AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE                                     \
+	(BIT(0) << AUX_RX_PHY_STATE_AUX_TX_P0_SHIFT)
+
+#define MTK_DP_AUX_P0_362C		  (AUX_OFFSET + 0x2C)
+#define AUX_NO_LENGTH_AUX_TX_P0_MASK	  BIT(0)
+#define AUX_NO_LENGTH_AUX_TX_P0_SHIFT	  0
+#define AUX_TX_AUXTX_OV_EN_AUX_TX_P0_MASK BIT(1)
+#define AUX_RESERVED_RW_0_AUX_TX_P0_MASK  GENMASK(15, 2)
+
+#define MTK_DP_AUX_P0_3630		     (AUX_OFFSET + 0x30)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_MASK  BIT(3)
+#define AUX_TX_REQUEST_READY_AUX_TX_P0_SHIFT GENMASK(1, 0)
+
+#define MTK_DP_AUX_P0_3634			(AUX_OFFSET + 0x34)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_MASK	GENMASK(15, 8)
+#define AUX_TX_OVER_SAMPLE_RATE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3640			      (AUX_OFFSET + 0x40)
+#define AUX_RX_RECV_COMPLETE_IRQ_TX_P0_MASK	      BIT(6)
+#define AUX_RX_AUX_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT  GENMASK(2, 1)
+#define AUX_RX_EDID_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT (BIT(0) | BIT(2))
+#define AUX_RX_MCCS_RECV_COMPLETE_IRQ_AUX_TX_P0_SHIFT BIT(2)
+#define AUX_RX_CMD_RECV_IRQ_AUX_TX_P0_SHIFT	      GENMASK(1, 0)
+#define AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(1)
+#define AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_MASK	      BIT(0)
+#define AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT	      0
+
+#define MTK_DP_AUX_P0_3644		   (AUX_OFFSET + 0x44)
+#define MCU_REQUEST_COMMAND_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3648		       (AUX_OFFSET + 0x48)
+#define MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK GENMASK(15, 0)
+
+#define MTK_DP_AUX_P0_364C		       (AUX_OFFSET + 0x4C)
+#define MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK GENMASK(3, 0)
+
+#define MTK_DP_AUX_P0_3650		      (AUX_OFFSET + 0x50)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_MASK	      GENMASK(15, 12)
+#define MCU_REQ_DATA_NUM_AUX_TX_P0_SHIFT      GENMASK(3, 2)
+#define PHY_FIFO_RST_AUX_TX_P0_MASK	      BIT(9)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_MASK  BIT(8)
+#define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3658	    (AUX_OFFSET + 0x58)
+#define AUX_TX_OV_EN_AUX_TX_P0_MASK BIT(0)
+
+#define MTK_DP_AUX_P0_3690		       (AUX_OFFSET + 0x90)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK  BIT(8)
+#define RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT BIT(3)
+
+#define MTK_DP_AUX_P0_3704				      (AUX_OFFSET + 0x104)
+#define AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_MASK BIT(1)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_MASK		      BIT(2)
+#define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_SHIFT		      BIT(1)
+
+#define MTK_DP_AUX_P0_3708 (AUX_OFFSET + 0x108)
+
+#define MTK_DP_AUX_P0_37C8	    (AUX_OFFSET + 0x1C8)
+#define MTK_ATOP_EN_AUX_TX_P0_MASK  BIT(0)
+#define MTK_ATOP_EN_AUX_TX_P0_SHIFT 0
+
+#define MTK_DP_TOP_PWR_STATE	       (TOP_OFFSET + 0x0)
+#define DP_PWR_STATE_MASK	       GENMASK(1, 0)
+#define DP_PWR_STATE_BANDGAP	       BIT(0)
+#define DP_PWR_STATE_BANDGAP_TPLL      BIT(1)
+#define DP_PWR_STATE_BANDGAP_TPLL_LANE GENMASK(1, 0)
+
+#define MTK_DP_TOP_SWING_EMP	(TOP_OFFSET + 0x4)
+#define DP_TX0_VOLT_SWING_MASK	GENMASK(1, 0)
+#define DP_TX0_VOLT_SWING_SHIFT 0
+#define DP_TX0_PRE_EMPH_MASK	GENMASK(3, 2)
+#define DP_TX0_PRE_EMPH_SHIFT	BIT(1)
+#define DP_TX1_VOLT_SWING_MASK	GENMASK(9, 8)
+#define DP_TX1_VOLT_SWING_SHIFT BIT(3)
+#define DP_TX1_PRE_EMPH_MASK	GENMASK(11, 10)
+#define DP_TX2_VOLT_SWING_MASK	GENMASK(17, 16)
+#define DP_TX2_PRE_EMPH_MASK	GENMASK(19, 18)
+#define DP_TX3_VOLT_SWING_MASK	GENMASK(25, 24)
+#define DP_TX3_PRE_EMPH_MASK	GENMASK(27, 26)
+
+#define MTK_DP_TOP_RESET_AND_PROBE (TOP_OFFSET + 0x20)
+#define SW_RST_B_SHIFT		   0
+#define SW_RST_B_PHYD		   (BIT(4) << SW_RST_B_SHIFT)
+
+#define MTK_DP_TOP_IRQ_STATUS	   (TOP_OFFSET + 0x28)
+#define RGS_IRQ_STATUS_SHIFT	   0
+#define RGS_IRQ_STATUS_TRANSMITTER (BIT(1) << RGS_IRQ_STATUS_SHIFT)
+
+#define MTK_DP_TOP_IRQ_MASK  (TOP_OFFSET + 0x2C)
+#define IRQ_MASK_AUX_TOP_IRQ BIT(2)
+
+#define MTK_DP_TOP_MEM_PD (TOP_OFFSET + 0x38)
+#define MEM_ISO_EN_SHIFT  0
+#define FUSE_SEL_SHIFT	  BIT(1)
+
+#endif /*_MTK_DP_REG_H_*/
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index e25ac61aac08..4e378eb34071 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -906,6 +906,9 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+	&mtk_dp_driver,
+#endif
 	&mtk_drm_platform_driver,
 	&mtk_dsi_driver,
 	&mtk_ethdr_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 8d3ff32b5364..04de9436ea85 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -59,6 +59,9 @@ extern struct platform_driver mtk_disp_ovl_adaptor_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
+#if IS_REACHABLE(CONFIG_DRM_MEDIATEK_DP)
+extern struct platform_driver mtk_dp_driver;
+#endif
 extern struct platform_driver mtk_dsi_driver;
 extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

This patch adds External DisplayPort support to the mt8195 eDP driver.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 8eb17ae82bfd..4789853ec5ff 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -164,6 +164,11 @@ static struct regmap_config mtk_dp_regmap_config = {
 	.name = "mtk-dp-registers",
 };
 
+static bool mtk_dp_is_edp(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp->next_bridge;
+}
+
 static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
 {
 	return container_of(b, struct mtk_dp, bridge);
@@ -1054,26 +1059,49 @@ static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
 	if (!cal_data->ln_tx_impsel_pmos)
 		return -ENOMEM;
 
-	cal_data->glb_bias_trim =
-		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
-	cal_data->clktx_impse =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	if (mtk_dp_is_edp(mtk_dp)) {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	} else {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[0] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 13) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[1] & 0xf, 0x8);
+	}
 
 	kfree(buf);
 
@@ -1224,7 +1252,10 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
 			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
 
-	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	else
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -2066,6 +2097,24 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	enum drm_connector_status ret = connector_status_disconnected;
+	u8 sink_count = 0;
+
+	if (mtk_dp_is_edp(mtk_dp))
+		return connector_status_connected;
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
+		if (DP_GET_SINK_COUNT(sink_count))
+			ret = connector_status_connected;
+	}
+
+	return ret;
+}
+
 static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
 				    struct drm_connector *connector)
 {
@@ -2422,6 +2471,7 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.atomic_disable = mtk_dp_bridge_atomic_disable,
 	.mode_valid = mtk_dp_bridge_mode_valid,
 	.get_edid = mtk_dp_get_edid,
+	.detect = mtk_dp_bdg_detect,
 };
 
 static int mtk_dp_probe(struct platform_device *pdev)
@@ -2443,7 +2493,11 @@ static int mtk_dp_probe(struct platform_device *pdev)
 
 
 	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
-	if (IS_ERR(mtk_dp->next_bridge)) {
+	if (IS_ERR(mtk_dp->next_bridge) && PTR_ERR(mtk_dp->next_bridge) == -ENODEV) {
+		dev_info(dev,
+			 "No panel connected in devicetree, continuing as external DP\n");
+		mtk_dp->next_bridge = NULL;
+	} else if (IS_ERR(mtk_dp->next_bridge)) {
 		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
 	}
 
@@ -2488,7 +2542,10 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	mtk_dp->bridge.ops =
 		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
 	drm_bridge_add(&mtk_dp->bridge);
-	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	else
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
@@ -2550,6 +2607,7 @@ static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
 
 static const struct of_device_id mtk_dp_of_match[] = {
 	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{ .compatible = "mediatek,mt8195-dp-tx" },
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

This patch adds External DisplayPort support to the mt8195 eDP driver.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 8eb17ae82bfd..4789853ec5ff 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -164,6 +164,11 @@ static struct regmap_config mtk_dp_regmap_config = {
 	.name = "mtk-dp-registers",
 };
 
+static bool mtk_dp_is_edp(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp->next_bridge;
+}
+
 static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
 {
 	return container_of(b, struct mtk_dp, bridge);
@@ -1054,26 +1059,49 @@ static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
 	if (!cal_data->ln_tx_impsel_pmos)
 		return -ENOMEM;
 
-	cal_data->glb_bias_trim =
-		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
-	cal_data->clktx_impse =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	if (mtk_dp_is_edp(mtk_dp)) {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	} else {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[0] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 13) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[1] & 0xf, 0x8);
+	}
 
 	kfree(buf);
 
@@ -1224,7 +1252,10 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
 			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
 
-	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	else
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -2066,6 +2097,24 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	enum drm_connector_status ret = connector_status_disconnected;
+	u8 sink_count = 0;
+
+	if (mtk_dp_is_edp(mtk_dp))
+		return connector_status_connected;
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
+		if (DP_GET_SINK_COUNT(sink_count))
+			ret = connector_status_connected;
+	}
+
+	return ret;
+}
+
 static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
 				    struct drm_connector *connector)
 {
@@ -2422,6 +2471,7 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.atomic_disable = mtk_dp_bridge_atomic_disable,
 	.mode_valid = mtk_dp_bridge_mode_valid,
 	.get_edid = mtk_dp_get_edid,
+	.detect = mtk_dp_bdg_detect,
 };
 
 static int mtk_dp_probe(struct platform_device *pdev)
@@ -2443,7 +2493,11 @@ static int mtk_dp_probe(struct platform_device *pdev)
 
 
 	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
-	if (IS_ERR(mtk_dp->next_bridge)) {
+	if (IS_ERR(mtk_dp->next_bridge) && PTR_ERR(mtk_dp->next_bridge) == -ENODEV) {
+		dev_info(dev,
+			 "No panel connected in devicetree, continuing as external DP\n");
+		mtk_dp->next_bridge = NULL;
+	} else if (IS_ERR(mtk_dp->next_bridge)) {
 		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
 	}
 
@@ -2488,7 +2542,10 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	mtk_dp->bridge.ops =
 		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
 	drm_bridge_add(&mtk_dp->bridge);
-	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	else
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
@@ -2550,6 +2607,7 @@ static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
 
 static const struct of_device_id mtk_dp_of_match[] = {
 	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{ .compatible = "mediatek,mt8195-dp-tx" },
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

This patch adds External DisplayPort support to the mt8195 eDP driver.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 8eb17ae82bfd..4789853ec5ff 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -164,6 +164,11 @@ static struct regmap_config mtk_dp_regmap_config = {
 	.name = "mtk-dp-registers",
 };
 
+static bool mtk_dp_is_edp(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp->next_bridge;
+}
+
 static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
 {
 	return container_of(b, struct mtk_dp, bridge);
@@ -1054,26 +1059,49 @@ static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
 	if (!cal_data->ln_tx_impsel_pmos)
 		return -ENOMEM;
 
-	cal_data->glb_bias_trim =
-		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
-	cal_data->clktx_impse =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	if (mtk_dp_is_edp(mtk_dp)) {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	} else {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[0] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 13) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[1] & 0xf, 0x8);
+	}
 
 	kfree(buf);
 
@@ -1224,7 +1252,10 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
 			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
 
-	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	else
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -2066,6 +2097,24 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	enum drm_connector_status ret = connector_status_disconnected;
+	u8 sink_count = 0;
+
+	if (mtk_dp_is_edp(mtk_dp))
+		return connector_status_connected;
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
+		if (DP_GET_SINK_COUNT(sink_count))
+			ret = connector_status_connected;
+	}
+
+	return ret;
+}
+
 static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
 				    struct drm_connector *connector)
 {
@@ -2422,6 +2471,7 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.atomic_disable = mtk_dp_bridge_atomic_disable,
 	.mode_valid = mtk_dp_bridge_mode_valid,
 	.get_edid = mtk_dp_get_edid,
+	.detect = mtk_dp_bdg_detect,
 };
 
 static int mtk_dp_probe(struct platform_device *pdev)
@@ -2443,7 +2493,11 @@ static int mtk_dp_probe(struct platform_device *pdev)
 
 
 	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
-	if (IS_ERR(mtk_dp->next_bridge)) {
+	if (IS_ERR(mtk_dp->next_bridge) && PTR_ERR(mtk_dp->next_bridge) == -ENODEV) {
+		dev_info(dev,
+			 "No panel connected in devicetree, continuing as external DP\n");
+		mtk_dp->next_bridge = NULL;
+	} else if (IS_ERR(mtk_dp->next_bridge)) {
 		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
 	}
 
@@ -2488,7 +2542,10 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	mtk_dp->bridge.ops =
 		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
 	drm_bridge_add(&mtk_dp->bridge);
-	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	else
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
@@ -2550,6 +2607,7 @@ static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
 
 static const struct of_device_id mtk_dp_of_match[] = {
 	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{ .compatible = "mediatek,mt8195-dp-tx" },
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

This patch adds External DisplayPort support to the mt8195 eDP driver.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 8eb17ae82bfd..4789853ec5ff 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -164,6 +164,11 @@ static struct regmap_config mtk_dp_regmap_config = {
 	.name = "mtk-dp-registers",
 };
 
+static bool mtk_dp_is_edp(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp->next_bridge;
+}
+
 static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
 {
 	return container_of(b, struct mtk_dp, bridge);
@@ -1054,26 +1059,49 @@ static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
 	if (!cal_data->ln_tx_impsel_pmos)
 		return -ENOMEM;
 
-	cal_data->glb_bias_trim =
-		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
-	cal_data->clktx_impse =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	if (mtk_dp_is_edp(mtk_dp)) {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	} else {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[0] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 13) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[1] & 0xf, 0x8);
+	}
 
 	kfree(buf);
 
@@ -1224,7 +1252,10 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
 			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
 
-	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	else
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -2066,6 +2097,24 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	enum drm_connector_status ret = connector_status_disconnected;
+	u8 sink_count = 0;
+
+	if (mtk_dp_is_edp(mtk_dp))
+		return connector_status_connected;
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
+		if (DP_GET_SINK_COUNT(sink_count))
+			ret = connector_status_connected;
+	}
+
+	return ret;
+}
+
 static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
 				    struct drm_connector *connector)
 {
@@ -2422,6 +2471,7 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.atomic_disable = mtk_dp_bridge_atomic_disable,
 	.mode_valid = mtk_dp_bridge_mode_valid,
 	.get_edid = mtk_dp_get_edid,
+	.detect = mtk_dp_bdg_detect,
 };
 
 static int mtk_dp_probe(struct platform_device *pdev)
@@ -2443,7 +2493,11 @@ static int mtk_dp_probe(struct platform_device *pdev)
 
 
 	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
-	if (IS_ERR(mtk_dp->next_bridge)) {
+	if (IS_ERR(mtk_dp->next_bridge) && PTR_ERR(mtk_dp->next_bridge) == -ENODEV) {
+		dev_info(dev,
+			 "No panel connected in devicetree, continuing as external DP\n");
+		mtk_dp->next_bridge = NULL;
+	} else if (IS_ERR(mtk_dp->next_bridge)) {
 		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
 	}
 
@@ -2488,7 +2542,10 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	mtk_dp->bridge.ops =
 		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
 	drm_bridge_add(&mtk_dp->bridge);
-	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	else
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
@@ -2550,6 +2607,7 @@ static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
 
 static const struct of_device_id mtk_dp_of_match[] = {
 	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{ .compatible = "mediatek,mt8195-dp-tx" },
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

This patch adds External DisplayPort support to the mt8195 eDP driver.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 8eb17ae82bfd..4789853ec5ff 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -164,6 +164,11 @@ static struct regmap_config mtk_dp_regmap_config = {
 	.name = "mtk-dp-registers",
 };
 
+static bool mtk_dp_is_edp(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp->next_bridge;
+}
+
 static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
 {
 	return container_of(b, struct mtk_dp, bridge);
@@ -1054,26 +1059,49 @@ static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
 	if (!cal_data->ln_tx_impsel_pmos)
 		return -ENOMEM;
 
-	cal_data->glb_bias_trim =
-		check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
-	cal_data->clktx_impse =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[0] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[1] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[2] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_pmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
-	cal_data->ln_tx_impsel_nmos[3] =
-		check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	if (mtk_dp_is_edp(mtk_dp)) {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
+	} else {
+		cal_data->glb_bias_trim =
+			check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[0] >> 27) & 0x1f, 0xf);
+		cal_data->clktx_impse =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 13) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 28) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[0] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 24) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 20) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[1] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 16) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 12) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[2] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 8) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_pmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 4) & 0xf, 0x8);
+		cal_data->ln_tx_impsel_nmos[3] =
+			check_cal_data_valid(mtk_dp, 1, 0xe, buf[1] & 0xf, 0x8);
+	}
 
 	kfree(buf);
 
@@ -1224,7 +1252,10 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
 			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
 
-	mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
+	else
+		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -2066,6 +2097,24 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
+{
+	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
+	enum drm_connector_status ret = connector_status_disconnected;
+	u8 sink_count = 0;
+
+	if (mtk_dp_is_edp(mtk_dp))
+		return connector_status_connected;
+
+	if (mtk_dp_plug_state(mtk_dp)) {
+		drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
+		if (DP_GET_SINK_COUNT(sink_count))
+			ret = connector_status_connected;
+	}
+
+	return ret;
+}
+
 static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
 				    struct drm_connector *connector)
 {
@@ -2422,6 +2471,7 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.atomic_disable = mtk_dp_bridge_atomic_disable,
 	.mode_valid = mtk_dp_bridge_mode_valid,
 	.get_edid = mtk_dp_get_edid,
+	.detect = mtk_dp_bdg_detect,
 };
 
 static int mtk_dp_probe(struct platform_device *pdev)
@@ -2443,7 +2493,11 @@ static int mtk_dp_probe(struct platform_device *pdev)
 
 
 	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
-	if (IS_ERR(mtk_dp->next_bridge)) {
+	if (IS_ERR(mtk_dp->next_bridge) && PTR_ERR(mtk_dp->next_bridge) == -ENODEV) {
+		dev_info(dev,
+			 "No panel connected in devicetree, continuing as external DP\n");
+		mtk_dp->next_bridge = NULL;
+	} else if (IS_ERR(mtk_dp->next_bridge)) {
 		return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
 	}
 
@@ -2488,7 +2542,10 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	mtk_dp->bridge.ops =
 		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
 	drm_bridge_add(&mtk_dp->bridge);
-	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	if (mtk_dp_is_edp(mtk_dp))
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+	else
+		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
@@ -2550,6 +2607,7 @@ static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
 
 static const struct of_device_id mtk_dp_of_match[] = {
 	{ .compatible = "mediatek,mt8195-edp-tx" },
+	{ .compatible = "mediatek,mt8195-dp-tx" },
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 20/21] drm/mediatek: add hpd debounce
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel

From: Jitao Shi <jitao.shi@mediatek.com>

From the DP spec 1.4a chapter 3.3, upstream devices should implement
HPD signal de-bouncing on an external connection.
A period of 100ms should be used to detect an HPD connect event.
To cover these cases, HPD de-bounce should be implemented only after
HPD low has been detected for at least 100ms.

Therefore,
1. If HPD is low (which means plugging out) for longer than 100ms:
   we need to do de-bouncing (which means we need to wait for 100ms).
2. If HPD low is for less than 100ms:
   we don't need to care about the de-bouncing.

In this patch, we start a 100ms timer and use a need_debounce boolean
to implement the feature.

Two cases when HPD is high:
1. If the timer is expired (>100ms):
   - need_debounce is true.
   - When HPD high (plugging event comes), need_debounce will be true
     and then we need to do de-bouncing (wait for 100ms).
2. If the timer is not expired (<100ms):
   - need_debounce is false.
   - When HPD high (plugging event comes), need_debounce will be false
     and no need to do de-bouncing.

HPD_______             __________________
          |            |<-  100ms   ->
          |____________|
          <-  100ms   ->

Without HPD de-bouncing, USB-C to HDMI Adapaters will not be detected.

The change has been successfully tested with the following devices:
- Dell Adapter - USB-C to HDMI
- Acer 1in1 HDMI dongle
- Ugreen 1in1 HDMI dongle
- innowatt HDMI + USB3 hub
- Acer 2in1 HDMI dongle
- Apple 3in1 HDMI dongle (A2119)
- J5Create 3in1 HDMI dongle (JAC379)

Tested-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 4789853ec5ff..c056bc3ca9f6 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -154,6 +154,8 @@ struct mtk_dp {
 	struct mutex dp_lock;
 
 	struct drm_connector *conn;
+	bool need_debounce;
+	struct timer_list debounce_timer;
 };
 
 static struct regmap_config mtk_dp_regmap_config = {
@@ -1970,6 +1972,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 	if (event < 0)
 		return IRQ_HANDLED;
 
+	if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
+		msleep(100);
+
 	if (mtk_dp->drm_dev) {
 		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
 		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
@@ -2047,6 +2052,11 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
 	}
 	train_info->cable_state_change = true;
 
+	if (!train_info->cable_plugged_in) {
+		mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1);
+		mtk_dp->need_debounce = false;
+	}
+
 	return IRQ_WAKE_THREAD;
 }
 
@@ -2474,6 +2484,13 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.detect = mtk_dp_bdg_detect,
 };
 
+static void mtk_dp_debounce_timer(struct timer_list *t)
+{
+	struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer);
+
+	mtk_dp->need_debounce = true;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2547,6 +2564,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	else
 		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
+	mtk_dp->need_debounce = true;
+	timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0);
+
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
@@ -2559,6 +2579,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 20/21] drm/mediatek: add hpd debounce
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Rex-BC Chen, dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

From: Jitao Shi <jitao.shi@mediatek.com>

From the DP spec 1.4a chapter 3.3, upstream devices should implement
HPD signal de-bouncing on an external connection.
A period of 100ms should be used to detect an HPD connect event.
To cover these cases, HPD de-bounce should be implemented only after
HPD low has been detected for at least 100ms.

Therefore,
1. If HPD is low (which means plugging out) for longer than 100ms:
   we need to do de-bouncing (which means we need to wait for 100ms).
2. If HPD low is for less than 100ms:
   we don't need to care about the de-bouncing.

In this patch, we start a 100ms timer and use a need_debounce boolean
to implement the feature.

Two cases when HPD is high:
1. If the timer is expired (>100ms):
   - need_debounce is true.
   - When HPD high (plugging event comes), need_debounce will be true
     and then we need to do de-bouncing (wait for 100ms).
2. If the timer is not expired (<100ms):
   - need_debounce is false.
   - When HPD high (plugging event comes), need_debounce will be false
     and no need to do de-bouncing.

HPD_______             __________________
          |            |<-  100ms   ->
          |____________|
          <-  100ms   ->

Without HPD de-bouncing, USB-C to HDMI Adapaters will not be detected.

The change has been successfully tested with the following devices:
- Dell Adapter - USB-C to HDMI
- Acer 1in1 HDMI dongle
- Ugreen 1in1 HDMI dongle
- innowatt HDMI + USB3 hub
- Acer 2in1 HDMI dongle
- Apple 3in1 HDMI dongle (A2119)
- J5Create 3in1 HDMI dongle (JAC379)

Tested-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 4789853ec5ff..c056bc3ca9f6 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -154,6 +154,8 @@ struct mtk_dp {
 	struct mutex dp_lock;
 
 	struct drm_connector *conn;
+	bool need_debounce;
+	struct timer_list debounce_timer;
 };
 
 static struct regmap_config mtk_dp_regmap_config = {
@@ -1970,6 +1972,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 	if (event < 0)
 		return IRQ_HANDLED;
 
+	if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
+		msleep(100);
+
 	if (mtk_dp->drm_dev) {
 		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
 		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
@@ -2047,6 +2052,11 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
 	}
 	train_info->cable_state_change = true;
 
+	if (!train_info->cable_plugged_in) {
+		mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1);
+		mtk_dp->need_debounce = false;
+	}
+
 	return IRQ_WAKE_THREAD;
 }
 
@@ -2474,6 +2484,13 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.detect = mtk_dp_bdg_detect,
 };
 
+static void mtk_dp_debounce_timer(struct timer_list *t)
+{
+	struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer);
+
+	mtk_dp->need_debounce = true;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2547,6 +2564,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	else
 		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
+	mtk_dp->need_debounce = true;
+	timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0);
+
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
@@ -2559,6 +2579,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 20/21] drm/mediatek: add hpd debounce
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Rex-BC Chen, dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

From: Jitao Shi <jitao.shi@mediatek.com>

From the DP spec 1.4a chapter 3.3, upstream devices should implement
HPD signal de-bouncing on an external connection.
A period of 100ms should be used to detect an HPD connect event.
To cover these cases, HPD de-bounce should be implemented only after
HPD low has been detected for at least 100ms.

Therefore,
1. If HPD is low (which means plugging out) for longer than 100ms:
   we need to do de-bouncing (which means we need to wait for 100ms).
2. If HPD low is for less than 100ms:
   we don't need to care about the de-bouncing.

In this patch, we start a 100ms timer and use a need_debounce boolean
to implement the feature.

Two cases when HPD is high:
1. If the timer is expired (>100ms):
   - need_debounce is true.
   - When HPD high (plugging event comes), need_debounce will be true
     and then we need to do de-bouncing (wait for 100ms).
2. If the timer is not expired (<100ms):
   - need_debounce is false.
   - When HPD high (plugging event comes), need_debounce will be false
     and no need to do de-bouncing.

HPD_______             __________________
          |            |<-  100ms   ->
          |____________|
          <-  100ms   ->

Without HPD de-bouncing, USB-C to HDMI Adapaters will not be detected.

The change has been successfully tested with the following devices:
- Dell Adapter - USB-C to HDMI
- Acer 1in1 HDMI dongle
- Ugreen 1in1 HDMI dongle
- innowatt HDMI + USB3 hub
- Acer 2in1 HDMI dongle
- Apple 3in1 HDMI dongle (A2119)
- J5Create 3in1 HDMI dongle (JAC379)

Tested-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 4789853ec5ff..c056bc3ca9f6 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -154,6 +154,8 @@ struct mtk_dp {
 	struct mutex dp_lock;
 
 	struct drm_connector *conn;
+	bool need_debounce;
+	struct timer_list debounce_timer;
 };
 
 static struct regmap_config mtk_dp_regmap_config = {
@@ -1970,6 +1972,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 	if (event < 0)
 		return IRQ_HANDLED;
 
+	if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
+		msleep(100);
+
 	if (mtk_dp->drm_dev) {
 		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
 		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
@@ -2047,6 +2052,11 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
 	}
 	train_info->cable_state_change = true;
 
+	if (!train_info->cable_plugged_in) {
+		mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1);
+		mtk_dp->need_debounce = false;
+	}
+
 	return IRQ_WAKE_THREAD;
 }
 
@@ -2474,6 +2484,13 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.detect = mtk_dp_bdg_detect,
 };
 
+static void mtk_dp_debounce_timer(struct timer_list *t)
+{
+	struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer);
+
+	mtk_dp->need_debounce = true;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2547,6 +2564,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	else
 		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
+	mtk_dp->need_debounce = true;
+	timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0);
+
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
@@ -2559,6 +2579,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
 
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 20/21] drm/mediatek: add hpd debounce
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Rex-BC Chen, dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

From: Jitao Shi <jitao.shi@mediatek.com>

From the DP spec 1.4a chapter 3.3, upstream devices should implement
HPD signal de-bouncing on an external connection.
A period of 100ms should be used to detect an HPD connect event.
To cover these cases, HPD de-bounce should be implemented only after
HPD low has been detected for at least 100ms.

Therefore,
1. If HPD is low (which means plugging out) for longer than 100ms:
   we need to do de-bouncing (which means we need to wait for 100ms).
2. If HPD low is for less than 100ms:
   we don't need to care about the de-bouncing.

In this patch, we start a 100ms timer and use a need_debounce boolean
to implement the feature.

Two cases when HPD is high:
1. If the timer is expired (>100ms):
   - need_debounce is true.
   - When HPD high (plugging event comes), need_debounce will be true
     and then we need to do de-bouncing (wait for 100ms).
2. If the timer is not expired (<100ms):
   - need_debounce is false.
   - When HPD high (plugging event comes), need_debounce will be false
     and no need to do de-bouncing.

HPD_______             __________________
          |            |<-  100ms   ->
          |____________|
          <-  100ms   ->

Without HPD de-bouncing, USB-C to HDMI Adapaters will not be detected.

The change has been successfully tested with the following devices:
- Dell Adapter - USB-C to HDMI
- Acer 1in1 HDMI dongle
- Ugreen 1in1 HDMI dongle
- innowatt HDMI + USB3 hub
- Acer 2in1 HDMI dongle
- Apple 3in1 HDMI dongle (A2119)
- J5Create 3in1 HDMI dongle (JAC379)

Tested-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 4789853ec5ff..c056bc3ca9f6 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -154,6 +154,8 @@ struct mtk_dp {
 	struct mutex dp_lock;
 
 	struct drm_connector *conn;
+	bool need_debounce;
+	struct timer_list debounce_timer;
 };
 
 static struct regmap_config mtk_dp_regmap_config = {
@@ -1970,6 +1972,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 	if (event < 0)
 		return IRQ_HANDLED;
 
+	if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
+		msleep(100);
+
 	if (mtk_dp->drm_dev) {
 		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
 		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
@@ -2047,6 +2052,11 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
 	}
 	train_info->cable_state_change = true;
 
+	if (!train_info->cable_plugged_in) {
+		mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1);
+		mtk_dp->need_debounce = false;
+	}
+
 	return IRQ_WAKE_THREAD;
 }
 
@@ -2474,6 +2484,13 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.detect = mtk_dp_bdg_detect,
 };
 
+static void mtk_dp_debounce_timer(struct timer_list *t)
+{
+	struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer);
+
+	mtk_dp->need_debounce = true;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2547,6 +2564,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	else
 		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
+	mtk_dp->need_debounce = true;
+	timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0);
+
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
@@ -2559,6 +2579,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 20/21] drm/mediatek: add hpd debounce
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Rex-BC Chen, dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

From: Jitao Shi <jitao.shi@mediatek.com>

From the DP spec 1.4a chapter 3.3, upstream devices should implement
HPD signal de-bouncing on an external connection.
A period of 100ms should be used to detect an HPD connect event.
To cover these cases, HPD de-bounce should be implemented only after
HPD low has been detected for at least 100ms.

Therefore,
1. If HPD is low (which means plugging out) for longer than 100ms:
   we need to do de-bouncing (which means we need to wait for 100ms).
2. If HPD low is for less than 100ms:
   we don't need to care about the de-bouncing.

In this patch, we start a 100ms timer and use a need_debounce boolean
to implement the feature.

Two cases when HPD is high:
1. If the timer is expired (>100ms):
   - need_debounce is true.
   - When HPD high (plugging event comes), need_debounce will be true
     and then we need to do de-bouncing (wait for 100ms).
2. If the timer is not expired (<100ms):
   - need_debounce is false.
   - When HPD high (plugging event comes), need_debounce will be false
     and no need to do de-bouncing.

HPD_______             __________________
          |            |<-  100ms   ->
          |____________|
          <-  100ms   ->

Without HPD de-bouncing, USB-C to HDMI Adapaters will not be detected.

The change has been successfully tested with the following devices:
- Dell Adapter - USB-C to HDMI
- Acer 1in1 HDMI dongle
- Ugreen 1in1 HDMI dongle
- innowatt HDMI + USB3 hub
- Acer 2in1 HDMI dongle
- Apple 3in1 HDMI dongle (A2119)
- J5Create 3in1 HDMI dongle (JAC379)

Tested-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 4789853ec5ff..c056bc3ca9f6 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -154,6 +154,8 @@ struct mtk_dp {
 	struct mutex dp_lock;
 
 	struct drm_connector *conn;
+	bool need_debounce;
+	struct timer_list debounce_timer;
 };
 
 static struct regmap_config mtk_dp_regmap_config = {
@@ -1970,6 +1972,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 	if (event < 0)
 		return IRQ_HANDLED;
 
+	if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
+		msleep(100);
+
 	if (mtk_dp->drm_dev) {
 		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
 		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
@@ -2047,6 +2052,11 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
 	}
 	train_info->cable_state_change = true;
 
+	if (!train_info->cable_plugged_in) {
+		mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1);
+		mtk_dp->need_debounce = false;
+	}
+
 	return IRQ_WAKE_THREAD;
 }
 
@@ -2474,6 +2484,13 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
 	.detect = mtk_dp_bdg_detect,
 };
 
+static void mtk_dp_debounce_timer(struct timer_list *t)
+{
+	struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer);
+
+	mtk_dp->need_debounce = true;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2547,6 +2564,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	else
 		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
+	mtk_dp->need_debounce = true;
+	timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0);
+
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
@@ -2559,6 +2579,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 21/21] drm/mediatek: DP audio support for mt8195
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:47   ` Guillaume Ranquet
  -1 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

This patch adds audio support to the DP driver for mt8195 with up to 8
channels.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 784 +++++++++++++++++++++++++++++-
 1 file changed, 777 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index c056bc3ca9f6..05da6565c7f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -108,9 +108,41 @@ enum mtk_dp_color_depth {
 	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
 };
 
+enum mtk_dp_sdp_type {
+	MTK_DP_SDP_NONE = 0x00,
+	MTK_DP_SDP_ACM = 0x01,
+	MTK_DP_SDP_ISRC = 0x02,
+	MTK_DP_SDP_AVI = 0x03,
+	MTK_DP_SDP_AUI = 0x04,
+	MTK_DP_SDP_SPD = 0x05,
+	MTK_DP_SDP_MPEG = 0x06,
+	MTK_DP_SDP_NTSC = 0x07,
+	MTK_DP_SDP_VSP = 0x08,
+	MTK_DP_SDP_VSC = 0x09,
+	MTK_DP_SDP_EXT = 0x0A,
+	MTK_DP_SDP_PPS0 = 0x0B,
+	MTK_DP_SDP_PPS1 = 0x0C,
+	MTK_DP_SDP_PPS2 = 0x0D,
+	MTK_DP_SDP_PPS3 = 0x0E,
+	MTK_DP_SDP_DRM = 0x10,
+	MTK_DP_SDP_MAX_NUM
+};
+
+struct mtk_dp_sdp_packet {
+	enum mtk_dp_sdp_type type;
+	struct dp_sdp sdp;
+};
+
+struct mtk_dp_audio_cfg {
+	int sample_rate;
+	int word_length_bits;
+	int channels;
+};
+
 struct mtk_dp_info {
 	enum mtk_dp_color_depth depth;
 	enum dp_pixelformat format;
+	struct mtk_dp_audio_cfg audio_caps;
 	struct mtk_dp_timings timings;
 };
 
@@ -148,10 +180,22 @@ struct mtk_dp {
 	struct clk *dp_tx_clk;
 
 	bool enabled;
+	bool audio_enable;
 
 	bool has_fec;
 	/* Protects the mtk_dp struct */
 	struct mutex dp_lock;
+	/* Protects the plugged_cb as it's used in both bridge ops and audio */
+	struct mutex update_plugged_status_lock;
+	/* Protects the eld data as it's used in both bridge ops and audio */
+	struct mutex eld_lock;
+	/* Protects edid as it is used in both bridge ops and IRQ handler */
+	struct mutex edid_lock;
+	struct edid *edid;
+
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
+	u8 connector_eld[MAX_ELD_BYTES];
 
 	struct drm_connector *conn;
 	bool need_debounce;
@@ -512,15 +556,363 @@ static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
 	return ret;
 }
 
+static int mtk_dp_audio_setup_channels(struct mtk_dp *mtk_dp,
+				       struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	u32 channel_enable_bits;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3324,
+				 AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX,
+			    AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(9), BIT(9));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_PRTY_REGEN_DP_ENC1_P0_MASK,
+			    AU_PRTY_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_CH_STS_REGEN_DP_ENC1_P0_MASK,
+			    AU_CH_STS_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK,
+			    AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	switch (cfg->channels) {
+	case 2:
+		channel_enable_bits = AUDIO_2CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_2CH_EN_DP_ENC0_P0_MASK;
+		break;
+	case 8:
+	default:
+		channel_enable_bits = AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_8CH_EN_DP_ENC0_P0_MASK;
+		break;
+	}
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+				 channel_enable_bits | AU_EN_DP_ENC0_P0_MASK,
+			   AUDIO_2CH_SEL_DP_ENC0_P0_MASK | AUDIO_2CH_EN_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_EN_DP_ENC0_P0_MASK | AU_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, 0, BIT(9));
+	if (ret)
+		return ret;
+
+	/* enable audio reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(0), BIT(0));
+
+	return ret;
+}
+
+static int mtk_dp_audio_channel_status_set(struct mtk_dp *mtk_dp,
+					   struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	struct snd_aes_iec958 iec = { 0 };
+
+	switch (cfg->sample_rate) {
+	case 32000:
+		iec.status[3] = IEC958_AES3_CON_FS_32000;
+		break;
+	case 44100:
+		iec.status[3] = IEC958_AES3_CON_FS_44100;
+		break;
+	case 48000:
+		iec.status[3] = IEC958_AES3_CON_FS_48000;
+		break;
+	case 88200:
+		iec.status[3] = IEC958_AES3_CON_FS_88200;
+		break;
+	case 96000:
+		iec.status[3] = IEC958_AES3_CON_FS_96000;
+		break;
+	case 192000:
+		iec.status[3] = IEC958_AES3_CON_FS_192000;
+		break;
+	default:
+		iec.status[3] = IEC958_AES3_CON_FS_NOTID;
+		break;
+	}
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16;
+		break;
+	case 20:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	case 24:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_24_20 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	default:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_NOTID;
+	}
+
+	/* IEC 60958 consumer channel status bits */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_308C,
+				 0,
+			   CH_STATUS_0_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3090,
+				 iec.status[3] << 8,
+			   CH_STATUS_1_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3094, iec.status[4],
+				 CH_STATUS_2_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_audio_sdp_asp_set_channels(struct mtk_dp *mtk_dp,
+					     int channels)
+{
+	if (channels != 2 && channels != 8)
+		channels = 8;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_312C,
+			   (channels - 1) << ASP_HB3_DP_ENC0_P0_SHIFT,
+			   ASP_HB2_DP_ENC0_P0_MASK | ASP_HB3_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_audio_set_divider(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK);
+}
+
 static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
 {
 	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
 		  HPD_DB_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+static int mtk_dp_sdp_trigger_packet(struct mtk_dp *mtk_dp,
+				     enum mtk_dp_sdp_type type)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, type,
+				 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, SDP_PACKET_W_DP_ENC1_P0,
+				 SDP_PACKET_W_DP_ENC1_P0);
+
+	return ret;
+}
+
+static void mtk_dp_sdp_set_data(struct mtk_dp *mtk_dp, u8 *data_bytes)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_ENC1_P0_3200, data_bytes, 0x10);
+}
+
+static void mtk_dp_sdp_set_header(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_sdp_type type,
+				  struct dp_sdp_header *header)
+{
+	u32 db_addr;
+
+	switch (type) {
+	case MTK_DP_SDP_DRM:
+		db_addr = MTK_DP_ENC0_P0_3138;
+		break;
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		db_addr = MTK_DP_ENC0_P0_3130;
+		break;
+	default:
+		db_addr = MTK_DP_ENC0_P0_30D8 + (type - MTK_DP_SDP_ACM) * 8;
+	}
+
+	mtk_dp_bulk_16bit_write(mtk_dp, db_addr, (u8 *)header, 4);
+}
+
+static const u32 mtk_dp_sdp_type_to_reg[MTK_DP_SDP_MAX_NUM] = {
+	/* MTK_DP_SDP_NONE => */ 0x0,
+	/* MTK_DP_SDP_ACM  => */ MTK_DP_ENC0_P0_30B4,
+	/* MTK_DP_SDP_ISRC => */ MTK_DP_ENC0_P0_30B4 + 1,
+	/* MTK_DP_SDP_AVI  => */ MTK_DP_ENC0_P0_30A4 + 1,
+	/* MTK_DP_SDP_AUI  => */ MTK_DP_ENC0_P0_30A8,
+	/* MTK_DP_SDP_SPD  => */ MTK_DP_ENC0_P0_30A8 + 1,
+	/* MTK_DP_SDP_MPEG => */ MTK_DP_ENC0_P0_30AC,
+	/* MTK_DP_SDP_NTSC => */ MTK_DP_ENC0_P0_30AC + 1,
+	/* MTK_DP_SDP_VSP  => */ MTK_DP_ENC0_P0_30B0,
+	/* MTK_DP_SDP_VSC  => */ MTK_DP_ENC0_P0_30B8,
+	/* MTK_DP_SDP_EXT  => */ MTK_DP_ENC0_P0_30B0 + 1,
+	/* MTK_DP_SDP_PPS0 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS1 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS2 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS3 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_DRM  => */ MTK_DP_ENC0_P0_31DC,
+};
+
+static int mtk_dp_disable_sdp(struct mtk_dp *mtk_dp, enum mtk_dp_sdp_type type)
+{
+	if (type == MTK_DP_SDP_NONE)
+		return -EINVAL;
+
+	/* Disable periodic send */
+	return mtk_dp_update_bits(mtk_dp, mtk_dp_sdp_type_to_reg[type] & 0xfffc, 0,
+			   0xFF << ((mtk_dp_sdp_type_to_reg[type] & 3) * 8));
+}
+
+static int mtk_dp_setup_sdp(struct mtk_dp *mtk_dp,
+			    struct mtk_dp_sdp_packet *packet)
+{
+	int ret = -EINVAL;
+
+	mtk_dp_sdp_set_data(mtk_dp, packet->sdp.db);
+	mtk_dp_sdp_set_header(mtk_dp, packet->type, &packet->sdp.sdp_header);
+
+	mtk_dp_disable_sdp(mtk_dp, packet->type);
+
+	switch (packet->type) {
+	case MTK_DP_SDP_NONE:
+		break;
+	case MTK_DP_SDP_ISRC:
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+					 ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+					 SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+					 ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_DRM:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31DC,
+					 5 << HDR0_CFG_DP_ENC0_P0_SHIFT,
+					 HDR0_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+				   ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+					   ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+				   SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+				   ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_ACM:
+	case MTK_DP_SDP_AVI:
+	case MTK_DP_SDP_AUI:
+	case MTK_DP_SDP_SPD:
+	case MTK_DP_SDP_MPEG:
+	case MTK_DP_SDP_NTSC:
+	case MTK_DP_SDP_VSP:
+	case MTK_DP_SDP_VSC:
+	case MTK_DP_SDP_EXT:
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		/* Enable periodic sending */
+		ret = mtk_dp_update_bits(mtk_dp,
+					 mtk_dp_sdp_type_to_reg[packet->type] & 0xfffc,
+					 0x05 << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8),
+					 0xff << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8));
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int mtk_dp_sdp_vsc_ext_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A0, 0,
+				 BIT(7) | BIT(8) | BIT(12));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_328C, 0, BIT(7));
+
+	return ret;
+}
+
+static int mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
 {
-	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+	return mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
 		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
@@ -1244,20 +1636,71 @@ static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
 			   DP_SCR_EN_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+static int mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 {
+	int ret;
 	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
 
 	if (enable)
 		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
-			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
-			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+				 VIDEO_MUTE_SEL_DP_ENC0_P0_MASK | VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	if (ret)
+		return ret;
 
 	if (mtk_dp_is_edp(mtk_dp))
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
 	else
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
+
+	return 0;
+}
+
+static int mtk_dp_audio_mute(struct mtk_dp *mtk_dp, bool mute)
+{
+	int ret;
+
+	if (mute) {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030,
+				   BIT(VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT) |
+				   BIT(VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT),
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088, 0,
+					 AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030, 0,
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+					 BIT(AU_EN_DP_ENC0_P0_SHIFT),
+				   AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Send one every two frames */
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0x0F,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+	}
+
+	return ret;
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -1327,6 +1770,83 @@ static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
 	mtk_dp->info.timings.frame_rate = 60;
 
 	mtk_dp->has_fec = false;
+	mtk_dp->audio_enable = false;
+}
+
+static int mtk_dp_sdp_set_down_cnt_init(struct mtk_dp *mtk_dp,
+					u32 sram_read_start)
+{
+	u32 sdp_down_cnt_init = 0;
+	u32 dc_offset;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.pix_rate_khz > 0)
+		sdp_down_cnt_init = sram_read_start *
+				    mtk_dp->train_info.link_rate * 2700 * 8 /
+				    (timings->pix_rate_khz * 4);
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x1A ?
+						  sdp_down_cnt_init :
+						  0x1A; /* 26 */
+		break;
+	case 2:
+		/* case for LowResolution && High Audio Sample Rate */
+		dc_offset = mode.vtotal <= 525 ? 0x04 : 0x00;
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x10 ?
+						  sdp_down_cnt_init :
+						  0x10 + dc_offset; /* 20 or 16 */
+		break;
+	case 4:
+	default:
+		sdp_down_cnt_init =
+			sdp_down_cnt_init > 0x06 ? sdp_down_cnt_init : 0x06; /*6 */
+		break;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+			   sdp_down_cnt_init
+				   << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			   SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_sdp_set_down_cnt_init_in_hblank(struct mtk_dp *mtk_dp)
+{
+	int pix_clk_mhz;
+	u32 dc_offset;
+	u32 spd_down_cnt_init = 0;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	pix_clk_mhz = mtk_dp->info.format == DP_PIXELFORMAT_YUV420 ?
+				    mtk_dp->info.timings.pix_rate_khz / 2000 :
+				    mtk_dp->info.timings.pix_rate_khz / 1000;
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		spd_down_cnt_init = 0x20;
+		break;
+	case 2:
+		dc_offset = (mode.vtotal <= 525) ? 0x14 : 0x00;
+		spd_down_cnt_init = 0x18 + dc_offset;
+		break;
+	case 4:
+	default:
+		dc_offset = (mode.vtotal <= 525) ? 0x08 : 0x00;
+		if (pix_clk_mhz > mtk_dp->train_info.link_rate * 27)
+			spd_down_cnt_init = 0x8;
+		else
+			spd_down_cnt_init = 0x10 + dc_offset;
+		break;
+	}
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364, spd_down_cnt_init,
+			   SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
 }
 
 static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
@@ -1343,6 +1863,8 @@ static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
 	}
 
 	mtk_dp_setup_encoder(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init_in_hblank(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init(mtk_dp, sram_read_start);
 }
 
 static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
@@ -1420,6 +1942,17 @@ static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
 	return 0;
 }
 
+static void mtk_dp_sdp_stop_sending(struct mtk_dp *mtk_dp)
+{
+	u8 packet_type;
+
+	for (packet_type = MTK_DP_SDP_ACM; packet_type < MTK_DP_SDP_MAX_NUM;
+	     packet_type++)
+		mtk_dp_disable_sdp(mtk_dp, packet_type);
+
+	mtk_dp_sdp_vsc_ext_disable(mtk_dp);
+}
+
 static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
 					  u8 dpcd_adjust_req[2])
 {
@@ -1725,6 +2258,52 @@ static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
 	return true;
 }
 
+static int mtk_dp_edid_parse_audio_capabilities(struct mtk_dp *mtk_dp,
+						struct mtk_dp_audio_cfg *cfg)
+{
+	struct cea_sad *sads;
+	int sad_count;
+	int i;
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->edid_lock);
+	if (!mtk_dp->edid) {
+		mutex_unlock(&mtk_dp->edid_lock);
+		dev_err(mtk_dp->dev, "EDID not found!\n");
+		return -EINVAL;
+	}
+
+	sad_count = drm_edid_to_sad(mtk_dp->edid, &sads);
+	mutex_unlock(&mtk_dp->edid_lock);
+	if (sad_count <= 0) {
+		drm_info(mtk_dp->drm_dev, "The SADs is NULL\n");
+		return 0;
+	}
+
+	for (i = 0; i < sad_count; i++) {
+		int sample_rate;
+		int word_length;
+		/* Only PCM supported at the moment */
+		if (sads[i].format != HDMI_AUDIO_CODING_TYPE_PCM)
+			continue;
+
+		sample_rate = drm_cea_sad_get_sample_rate(&sads[i]);
+		word_length =
+			drm_cea_sad_get_uncompressed_word_length(&sads[i]);
+		if (sample_rate <= 0 || word_length <= 0)
+			continue;
+
+		cfg->channels = sads[i].channels;
+		cfg->word_length_bits = word_length;
+		cfg->sample_rate = sample_rate;
+		ret = 1;
+		break;
+	}
+	kfree(sads);
+
+	return ret;
+}
+
 static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
 {
 	phy_reset(mtk_dp->phy);
@@ -1830,6 +2409,48 @@ static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
 	}
 }
 
+static void mtk_dp_audio_sdp_setup(struct mtk_dp *mtk_dp,
+				   struct mtk_dp_audio_cfg *cfg)
+{
+	struct mtk_dp_sdp_packet packet;
+	struct hdmi_audio_infoframe frame;
+
+	hdmi_audio_infoframe_init(&frame);
+	frame.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;
+	frame.channels = cfg->channels;
+	frame.sample_frequency = cfg->sample_rate;
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		break;
+	case 20:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
+		break;
+	case 24:
+	default:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
+		break;
+	}
+
+	packet.type = MTK_DP_SDP_AUI;
+	hdmi_audio_infoframe_pack_for_dp(&frame, &packet.sdp,
+					 MTK_DP_DP_VERSION_11);
+
+	mtk_dp_audio_sdp_asp_set_channels(mtk_dp, cfg->channels);
+	mtk_dp_setup_sdp(mtk_dp, &packet);
+}
+
+static void mtk_dp_audio_setup(struct mtk_dp *mtk_dp,
+			       struct mtk_dp_audio_cfg *cfg)
+{
+	mtk_dp_audio_sdp_setup(mtk_dp, cfg);
+	mtk_dp_audio_channel_status_set(mtk_dp, cfg);
+
+	mtk_dp_audio_setup_channels(mtk_dp, cfg);
+	mtk_dp_audio_set_divider(mtk_dp);
+}
+
 static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
 {
 	mtk_dp_mn_overwrite_disable(mtk_dp);
@@ -1845,6 +2466,7 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 	switch (mtk_dp->state) {
 	case MTK_DP_STATE_INITIAL:
 		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp_audio_mute(mtk_dp, true);
 		mtk_dp->state = MTK_DP_STATE_IDLE;
 		break;
 
@@ -1857,12 +2479,19 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 		mtk_dp_video_config(mtk_dp);
 		mtk_dp_video_enable(mtk_dp, true);
 
+		if (mtk_dp->audio_enable) {
+			mtk_dp_audio_setup(mtk_dp, &mtk_dp->info.audio_caps);
+			mtk_dp_audio_mute(mtk_dp, false);
+		}
+
 		mtk_dp->state = MTK_DP_STATE_NORMAL;
 		break;
 
 	case MTK_DP_STATE_NORMAL:
 		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 			mtk_dp->state = MTK_DP_STATE_IDLE;
 		}
 		break;
@@ -1901,7 +2530,15 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			}
 			break;
 
-		case MTK_DP_TRAIN_STATE_CHECKEDID:
+		case MTK_DP_TRAIN_STATE_CHECKEDID: {
+			int caps_found = mtk_dp_edid_parse_audio_capabilities(mtk_dp,
+				&mtk_dp->info.audio_caps);
+			mtk_dp->audio_enable = caps_found > 0;
+			if (!mtk_dp->audio_enable)
+				memset(&mtk_dp->info.audio_caps, 0,
+				       sizeof(mtk_dp->info.audio_caps));
+		}
+
 			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
 			break;
 
@@ -1914,6 +2551,7 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			ret = mtk_dp_train_start(mtk_dp);
 			if (ret == 0) {
 				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp_audio_mute(mtk_dp, true);
 				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
 				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
 			} else if (ret != -EAGAIN) {
@@ -1988,11 +2626,13 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 		if (!mtk_dp->train_info.cable_plugged_in ||
 		    !mtk_dp_plug_state(mtk_dp)) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
 
 			mtk_dp_initialize_priv_data(mtk_dp);
 			mtk_dp_set_idle_pattern(mtk_dp, true);
 			if (mtk_dp->has_fec)
 				mtk_dp_fec_enable(mtk_dp, false);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 
 			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
 					   DP_PWR_STATE_BANDGAP_TPLL,
@@ -2107,6 +2747,18 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static void mtk_dp_update_plugged_status(struct mtk_dp *mtk_dp)
+{
+	bool connected, has_audio;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	connected = mtk_dp_plug_state(mtk_dp);
+	has_audio = drm_detect_monitor_audio(mtk_dp->edid);
+	if (mtk_dp->plugged_cb && mtk_dp->codec_dev)
+		mtk_dp->plugged_cb(mtk_dp->codec_dev, connected & has_audio);
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+}
+
 static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 {
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
@@ -2122,6 +2774,7 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 			ret = connector_status_connected;
 	}
 
+	mtk_dp_update_plugged_status(mtk_dp);
 	return ret;
 }
 
@@ -2308,6 +2961,7 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	mtk_dp->state = MTK_DP_STATE_IDLE;
 	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
 
@@ -2345,6 +2999,10 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
 		return;
 	}
 
+	mutex_lock(&mtk_dp->eld_lock);
+	memcpy(mtk_dp->connector_eld, mtk_dp->conn->eld, MAX_ELD_BYTES);
+	mutex_unlock(&mtk_dp->eld_lock);
+
 	mtk_dp->enabled = true;
 }
 
@@ -2491,6 +3149,104 @@ static void mtk_dp_debounce_timer(struct timer_list *t)
 	mtk_dp->need_debounce = true;
 }
 
+/*
+ * HDMI audio codec callbacks
+ */
+static int mtk_dp_audio_hw_params(struct device *dev, void *data,
+				  struct hdmi_codec_daifmt *daifmt,
+				  struct hdmi_codec_params *params)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct mtk_dp_audio_cfg cfg;
+
+	if (!mtk_dp->enabled) {
+		pr_err("%s, DP is not ready!\n", __func__);
+		return -ENODEV;
+	}
+
+	cfg.channels = params->cea.channels;
+	cfg.sample_rate = params->sample_rate;
+	cfg.word_length_bits = 24;
+
+	mtk_dp_audio_setup(mtk_dp, &cfg);
+
+	return 0;
+}
+
+static int mtk_dp_audio_startup(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, false);
+
+	return 0;
+}
+
+static void mtk_dp_audio_shutdown(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, true);
+}
+
+static int mtk_dp_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
+				size_t len)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp->enabled)
+		memcpy(buf, mtk_dp->connector_eld, len);
+	else
+		memset(buf, 0, len);
+
+	return 0;
+}
+
+static int mtk_dp_audio_hook_plugged_cb(struct device *dev, void *data,
+					hdmi_codec_plugged_cb fn,
+					struct device *codec_dev)
+{
+	struct mtk_dp *mtk_dp = data;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	mtk_dp->plugged_cb = fn;
+	mtk_dp->codec_dev = codec_dev;
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+
+	mtk_dp_update_plugged_status(mtk_dp);
+
+	return 0;
+}
+
+static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
+	.hw_params = mtk_dp_audio_hw_params,
+	.audio_startup = mtk_dp_audio_startup,
+	.audio_shutdown = mtk_dp_audio_shutdown,
+	.get_eld = mtk_dp_audio_get_eld,
+	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
+	.no_capture_mute = 1,
+};
+
+static int mtk_dp_register_audio_driver(struct device *dev)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct hdmi_codec_pdata codec_data = {
+		.ops = &mtk_dp_audio_codec_ops,
+		.max_i2s_channels = 8,
+		.i2s = 1,
+		.data = mtk_dp,
+	};
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO, &codec_data,
+					     sizeof(codec_data));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2534,9 +3290,21 @@ static int mtk_dp_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
 
 	mutex_init(&mtk_dp->dp_lock);
+	mutex_init(&mtk_dp->edid_lock);
+	mutex_init(&mtk_dp->eld_lock);
+	mutex_init(&mtk_dp->update_plugged_status_lock);
 
 	platform_set_drvdata(pdev, mtk_dp);
 
+	if (!mtk_dp_is_edp(mtk_dp)) {
+		ret = mtk_dp_register_audio_driver(dev);
+		if (ret) {
+			dev_err(dev, "Failed to register audio driver: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
 							PLATFORM_DEVID_AUTO,
 							&mtk_dp->regs,
@@ -2579,6 +3347,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 21/21] drm/mediatek: DP audio support for mt8195
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

This patch adds audio support to the DP driver for mt8195 with up to 8
channels.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 784 +++++++++++++++++++++++++++++-
 1 file changed, 777 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index c056bc3ca9f6..05da6565c7f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -108,9 +108,41 @@ enum mtk_dp_color_depth {
 	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
 };
 
+enum mtk_dp_sdp_type {
+	MTK_DP_SDP_NONE = 0x00,
+	MTK_DP_SDP_ACM = 0x01,
+	MTK_DP_SDP_ISRC = 0x02,
+	MTK_DP_SDP_AVI = 0x03,
+	MTK_DP_SDP_AUI = 0x04,
+	MTK_DP_SDP_SPD = 0x05,
+	MTK_DP_SDP_MPEG = 0x06,
+	MTK_DP_SDP_NTSC = 0x07,
+	MTK_DP_SDP_VSP = 0x08,
+	MTK_DP_SDP_VSC = 0x09,
+	MTK_DP_SDP_EXT = 0x0A,
+	MTK_DP_SDP_PPS0 = 0x0B,
+	MTK_DP_SDP_PPS1 = 0x0C,
+	MTK_DP_SDP_PPS2 = 0x0D,
+	MTK_DP_SDP_PPS3 = 0x0E,
+	MTK_DP_SDP_DRM = 0x10,
+	MTK_DP_SDP_MAX_NUM
+};
+
+struct mtk_dp_sdp_packet {
+	enum mtk_dp_sdp_type type;
+	struct dp_sdp sdp;
+};
+
+struct mtk_dp_audio_cfg {
+	int sample_rate;
+	int word_length_bits;
+	int channels;
+};
+
 struct mtk_dp_info {
 	enum mtk_dp_color_depth depth;
 	enum dp_pixelformat format;
+	struct mtk_dp_audio_cfg audio_caps;
 	struct mtk_dp_timings timings;
 };
 
@@ -148,10 +180,22 @@ struct mtk_dp {
 	struct clk *dp_tx_clk;
 
 	bool enabled;
+	bool audio_enable;
 
 	bool has_fec;
 	/* Protects the mtk_dp struct */
 	struct mutex dp_lock;
+	/* Protects the plugged_cb as it's used in both bridge ops and audio */
+	struct mutex update_plugged_status_lock;
+	/* Protects the eld data as it's used in both bridge ops and audio */
+	struct mutex eld_lock;
+	/* Protects edid as it is used in both bridge ops and IRQ handler */
+	struct mutex edid_lock;
+	struct edid *edid;
+
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
+	u8 connector_eld[MAX_ELD_BYTES];
 
 	struct drm_connector *conn;
 	bool need_debounce;
@@ -512,15 +556,363 @@ static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
 	return ret;
 }
 
+static int mtk_dp_audio_setup_channels(struct mtk_dp *mtk_dp,
+				       struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	u32 channel_enable_bits;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3324,
+				 AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX,
+			    AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(9), BIT(9));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_PRTY_REGEN_DP_ENC1_P0_MASK,
+			    AU_PRTY_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_CH_STS_REGEN_DP_ENC1_P0_MASK,
+			    AU_CH_STS_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK,
+			    AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	switch (cfg->channels) {
+	case 2:
+		channel_enable_bits = AUDIO_2CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_2CH_EN_DP_ENC0_P0_MASK;
+		break;
+	case 8:
+	default:
+		channel_enable_bits = AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_8CH_EN_DP_ENC0_P0_MASK;
+		break;
+	}
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+				 channel_enable_bits | AU_EN_DP_ENC0_P0_MASK,
+			   AUDIO_2CH_SEL_DP_ENC0_P0_MASK | AUDIO_2CH_EN_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_EN_DP_ENC0_P0_MASK | AU_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, 0, BIT(9));
+	if (ret)
+		return ret;
+
+	/* enable audio reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(0), BIT(0));
+
+	return ret;
+}
+
+static int mtk_dp_audio_channel_status_set(struct mtk_dp *mtk_dp,
+					   struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	struct snd_aes_iec958 iec = { 0 };
+
+	switch (cfg->sample_rate) {
+	case 32000:
+		iec.status[3] = IEC958_AES3_CON_FS_32000;
+		break;
+	case 44100:
+		iec.status[3] = IEC958_AES3_CON_FS_44100;
+		break;
+	case 48000:
+		iec.status[3] = IEC958_AES3_CON_FS_48000;
+		break;
+	case 88200:
+		iec.status[3] = IEC958_AES3_CON_FS_88200;
+		break;
+	case 96000:
+		iec.status[3] = IEC958_AES3_CON_FS_96000;
+		break;
+	case 192000:
+		iec.status[3] = IEC958_AES3_CON_FS_192000;
+		break;
+	default:
+		iec.status[3] = IEC958_AES3_CON_FS_NOTID;
+		break;
+	}
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16;
+		break;
+	case 20:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	case 24:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_24_20 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	default:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_NOTID;
+	}
+
+	/* IEC 60958 consumer channel status bits */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_308C,
+				 0,
+			   CH_STATUS_0_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3090,
+				 iec.status[3] << 8,
+			   CH_STATUS_1_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3094, iec.status[4],
+				 CH_STATUS_2_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_audio_sdp_asp_set_channels(struct mtk_dp *mtk_dp,
+					     int channels)
+{
+	if (channels != 2 && channels != 8)
+		channels = 8;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_312C,
+			   (channels - 1) << ASP_HB3_DP_ENC0_P0_SHIFT,
+			   ASP_HB2_DP_ENC0_P0_MASK | ASP_HB3_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_audio_set_divider(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK);
+}
+
 static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
 {
 	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
 		  HPD_DB_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+static int mtk_dp_sdp_trigger_packet(struct mtk_dp *mtk_dp,
+				     enum mtk_dp_sdp_type type)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, type,
+				 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, SDP_PACKET_W_DP_ENC1_P0,
+				 SDP_PACKET_W_DP_ENC1_P0);
+
+	return ret;
+}
+
+static void mtk_dp_sdp_set_data(struct mtk_dp *mtk_dp, u8 *data_bytes)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_ENC1_P0_3200, data_bytes, 0x10);
+}
+
+static void mtk_dp_sdp_set_header(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_sdp_type type,
+				  struct dp_sdp_header *header)
+{
+	u32 db_addr;
+
+	switch (type) {
+	case MTK_DP_SDP_DRM:
+		db_addr = MTK_DP_ENC0_P0_3138;
+		break;
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		db_addr = MTK_DP_ENC0_P0_3130;
+		break;
+	default:
+		db_addr = MTK_DP_ENC0_P0_30D8 + (type - MTK_DP_SDP_ACM) * 8;
+	}
+
+	mtk_dp_bulk_16bit_write(mtk_dp, db_addr, (u8 *)header, 4);
+}
+
+static const u32 mtk_dp_sdp_type_to_reg[MTK_DP_SDP_MAX_NUM] = {
+	/* MTK_DP_SDP_NONE => */ 0x0,
+	/* MTK_DP_SDP_ACM  => */ MTK_DP_ENC0_P0_30B4,
+	/* MTK_DP_SDP_ISRC => */ MTK_DP_ENC0_P0_30B4 + 1,
+	/* MTK_DP_SDP_AVI  => */ MTK_DP_ENC0_P0_30A4 + 1,
+	/* MTK_DP_SDP_AUI  => */ MTK_DP_ENC0_P0_30A8,
+	/* MTK_DP_SDP_SPD  => */ MTK_DP_ENC0_P0_30A8 + 1,
+	/* MTK_DP_SDP_MPEG => */ MTK_DP_ENC0_P0_30AC,
+	/* MTK_DP_SDP_NTSC => */ MTK_DP_ENC0_P0_30AC + 1,
+	/* MTK_DP_SDP_VSP  => */ MTK_DP_ENC0_P0_30B0,
+	/* MTK_DP_SDP_VSC  => */ MTK_DP_ENC0_P0_30B8,
+	/* MTK_DP_SDP_EXT  => */ MTK_DP_ENC0_P0_30B0 + 1,
+	/* MTK_DP_SDP_PPS0 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS1 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS2 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS3 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_DRM  => */ MTK_DP_ENC0_P0_31DC,
+};
+
+static int mtk_dp_disable_sdp(struct mtk_dp *mtk_dp, enum mtk_dp_sdp_type type)
+{
+	if (type == MTK_DP_SDP_NONE)
+		return -EINVAL;
+
+	/* Disable periodic send */
+	return mtk_dp_update_bits(mtk_dp, mtk_dp_sdp_type_to_reg[type] & 0xfffc, 0,
+			   0xFF << ((mtk_dp_sdp_type_to_reg[type] & 3) * 8));
+}
+
+static int mtk_dp_setup_sdp(struct mtk_dp *mtk_dp,
+			    struct mtk_dp_sdp_packet *packet)
+{
+	int ret = -EINVAL;
+
+	mtk_dp_sdp_set_data(mtk_dp, packet->sdp.db);
+	mtk_dp_sdp_set_header(mtk_dp, packet->type, &packet->sdp.sdp_header);
+
+	mtk_dp_disable_sdp(mtk_dp, packet->type);
+
+	switch (packet->type) {
+	case MTK_DP_SDP_NONE:
+		break;
+	case MTK_DP_SDP_ISRC:
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+					 ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+					 SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+					 ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_DRM:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31DC,
+					 5 << HDR0_CFG_DP_ENC0_P0_SHIFT,
+					 HDR0_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+				   ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+					   ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+				   SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+				   ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_ACM:
+	case MTK_DP_SDP_AVI:
+	case MTK_DP_SDP_AUI:
+	case MTK_DP_SDP_SPD:
+	case MTK_DP_SDP_MPEG:
+	case MTK_DP_SDP_NTSC:
+	case MTK_DP_SDP_VSP:
+	case MTK_DP_SDP_VSC:
+	case MTK_DP_SDP_EXT:
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		/* Enable periodic sending */
+		ret = mtk_dp_update_bits(mtk_dp,
+					 mtk_dp_sdp_type_to_reg[packet->type] & 0xfffc,
+					 0x05 << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8),
+					 0xff << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8));
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int mtk_dp_sdp_vsc_ext_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A0, 0,
+				 BIT(7) | BIT(8) | BIT(12));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_328C, 0, BIT(7));
+
+	return ret;
+}
+
+static int mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
 {
-	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+	return mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
 		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
@@ -1244,20 +1636,71 @@ static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
 			   DP_SCR_EN_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+static int mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 {
+	int ret;
 	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
 
 	if (enable)
 		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
-			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
-			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+				 VIDEO_MUTE_SEL_DP_ENC0_P0_MASK | VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	if (ret)
+		return ret;
 
 	if (mtk_dp_is_edp(mtk_dp))
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
 	else
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
+
+	return 0;
+}
+
+static int mtk_dp_audio_mute(struct mtk_dp *mtk_dp, bool mute)
+{
+	int ret;
+
+	if (mute) {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030,
+				   BIT(VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT) |
+				   BIT(VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT),
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088, 0,
+					 AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030, 0,
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+					 BIT(AU_EN_DP_ENC0_P0_SHIFT),
+				   AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Send one every two frames */
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0x0F,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+	}
+
+	return ret;
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -1327,6 +1770,83 @@ static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
 	mtk_dp->info.timings.frame_rate = 60;
 
 	mtk_dp->has_fec = false;
+	mtk_dp->audio_enable = false;
+}
+
+static int mtk_dp_sdp_set_down_cnt_init(struct mtk_dp *mtk_dp,
+					u32 sram_read_start)
+{
+	u32 sdp_down_cnt_init = 0;
+	u32 dc_offset;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.pix_rate_khz > 0)
+		sdp_down_cnt_init = sram_read_start *
+				    mtk_dp->train_info.link_rate * 2700 * 8 /
+				    (timings->pix_rate_khz * 4);
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x1A ?
+						  sdp_down_cnt_init :
+						  0x1A; /* 26 */
+		break;
+	case 2:
+		/* case for LowResolution && High Audio Sample Rate */
+		dc_offset = mode.vtotal <= 525 ? 0x04 : 0x00;
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x10 ?
+						  sdp_down_cnt_init :
+						  0x10 + dc_offset; /* 20 or 16 */
+		break;
+	case 4:
+	default:
+		sdp_down_cnt_init =
+			sdp_down_cnt_init > 0x06 ? sdp_down_cnt_init : 0x06; /*6 */
+		break;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+			   sdp_down_cnt_init
+				   << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			   SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_sdp_set_down_cnt_init_in_hblank(struct mtk_dp *mtk_dp)
+{
+	int pix_clk_mhz;
+	u32 dc_offset;
+	u32 spd_down_cnt_init = 0;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	pix_clk_mhz = mtk_dp->info.format == DP_PIXELFORMAT_YUV420 ?
+				    mtk_dp->info.timings.pix_rate_khz / 2000 :
+				    mtk_dp->info.timings.pix_rate_khz / 1000;
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		spd_down_cnt_init = 0x20;
+		break;
+	case 2:
+		dc_offset = (mode.vtotal <= 525) ? 0x14 : 0x00;
+		spd_down_cnt_init = 0x18 + dc_offset;
+		break;
+	case 4:
+	default:
+		dc_offset = (mode.vtotal <= 525) ? 0x08 : 0x00;
+		if (pix_clk_mhz > mtk_dp->train_info.link_rate * 27)
+			spd_down_cnt_init = 0x8;
+		else
+			spd_down_cnt_init = 0x10 + dc_offset;
+		break;
+	}
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364, spd_down_cnt_init,
+			   SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
 }
 
 static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
@@ -1343,6 +1863,8 @@ static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
 	}
 
 	mtk_dp_setup_encoder(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init_in_hblank(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init(mtk_dp, sram_read_start);
 }
 
 static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
@@ -1420,6 +1942,17 @@ static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
 	return 0;
 }
 
+static void mtk_dp_sdp_stop_sending(struct mtk_dp *mtk_dp)
+{
+	u8 packet_type;
+
+	for (packet_type = MTK_DP_SDP_ACM; packet_type < MTK_DP_SDP_MAX_NUM;
+	     packet_type++)
+		mtk_dp_disable_sdp(mtk_dp, packet_type);
+
+	mtk_dp_sdp_vsc_ext_disable(mtk_dp);
+}
+
 static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
 					  u8 dpcd_adjust_req[2])
 {
@@ -1725,6 +2258,52 @@ static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
 	return true;
 }
 
+static int mtk_dp_edid_parse_audio_capabilities(struct mtk_dp *mtk_dp,
+						struct mtk_dp_audio_cfg *cfg)
+{
+	struct cea_sad *sads;
+	int sad_count;
+	int i;
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->edid_lock);
+	if (!mtk_dp->edid) {
+		mutex_unlock(&mtk_dp->edid_lock);
+		dev_err(mtk_dp->dev, "EDID not found!\n");
+		return -EINVAL;
+	}
+
+	sad_count = drm_edid_to_sad(mtk_dp->edid, &sads);
+	mutex_unlock(&mtk_dp->edid_lock);
+	if (sad_count <= 0) {
+		drm_info(mtk_dp->drm_dev, "The SADs is NULL\n");
+		return 0;
+	}
+
+	for (i = 0; i < sad_count; i++) {
+		int sample_rate;
+		int word_length;
+		/* Only PCM supported at the moment */
+		if (sads[i].format != HDMI_AUDIO_CODING_TYPE_PCM)
+			continue;
+
+		sample_rate = drm_cea_sad_get_sample_rate(&sads[i]);
+		word_length =
+			drm_cea_sad_get_uncompressed_word_length(&sads[i]);
+		if (sample_rate <= 0 || word_length <= 0)
+			continue;
+
+		cfg->channels = sads[i].channels;
+		cfg->word_length_bits = word_length;
+		cfg->sample_rate = sample_rate;
+		ret = 1;
+		break;
+	}
+	kfree(sads);
+
+	return ret;
+}
+
 static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
 {
 	phy_reset(mtk_dp->phy);
@@ -1830,6 +2409,48 @@ static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
 	}
 }
 
+static void mtk_dp_audio_sdp_setup(struct mtk_dp *mtk_dp,
+				   struct mtk_dp_audio_cfg *cfg)
+{
+	struct mtk_dp_sdp_packet packet;
+	struct hdmi_audio_infoframe frame;
+
+	hdmi_audio_infoframe_init(&frame);
+	frame.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;
+	frame.channels = cfg->channels;
+	frame.sample_frequency = cfg->sample_rate;
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		break;
+	case 20:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
+		break;
+	case 24:
+	default:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
+		break;
+	}
+
+	packet.type = MTK_DP_SDP_AUI;
+	hdmi_audio_infoframe_pack_for_dp(&frame, &packet.sdp,
+					 MTK_DP_DP_VERSION_11);
+
+	mtk_dp_audio_sdp_asp_set_channels(mtk_dp, cfg->channels);
+	mtk_dp_setup_sdp(mtk_dp, &packet);
+}
+
+static void mtk_dp_audio_setup(struct mtk_dp *mtk_dp,
+			       struct mtk_dp_audio_cfg *cfg)
+{
+	mtk_dp_audio_sdp_setup(mtk_dp, cfg);
+	mtk_dp_audio_channel_status_set(mtk_dp, cfg);
+
+	mtk_dp_audio_setup_channels(mtk_dp, cfg);
+	mtk_dp_audio_set_divider(mtk_dp);
+}
+
 static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
 {
 	mtk_dp_mn_overwrite_disable(mtk_dp);
@@ -1845,6 +2466,7 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 	switch (mtk_dp->state) {
 	case MTK_DP_STATE_INITIAL:
 		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp_audio_mute(mtk_dp, true);
 		mtk_dp->state = MTK_DP_STATE_IDLE;
 		break;
 
@@ -1857,12 +2479,19 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 		mtk_dp_video_config(mtk_dp);
 		mtk_dp_video_enable(mtk_dp, true);
 
+		if (mtk_dp->audio_enable) {
+			mtk_dp_audio_setup(mtk_dp, &mtk_dp->info.audio_caps);
+			mtk_dp_audio_mute(mtk_dp, false);
+		}
+
 		mtk_dp->state = MTK_DP_STATE_NORMAL;
 		break;
 
 	case MTK_DP_STATE_NORMAL:
 		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 			mtk_dp->state = MTK_DP_STATE_IDLE;
 		}
 		break;
@@ -1901,7 +2530,15 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			}
 			break;
 
-		case MTK_DP_TRAIN_STATE_CHECKEDID:
+		case MTK_DP_TRAIN_STATE_CHECKEDID: {
+			int caps_found = mtk_dp_edid_parse_audio_capabilities(mtk_dp,
+				&mtk_dp->info.audio_caps);
+			mtk_dp->audio_enable = caps_found > 0;
+			if (!mtk_dp->audio_enable)
+				memset(&mtk_dp->info.audio_caps, 0,
+				       sizeof(mtk_dp->info.audio_caps));
+		}
+
 			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
 			break;
 
@@ -1914,6 +2551,7 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			ret = mtk_dp_train_start(mtk_dp);
 			if (ret == 0) {
 				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp_audio_mute(mtk_dp, true);
 				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
 				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
 			} else if (ret != -EAGAIN) {
@@ -1988,11 +2626,13 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 		if (!mtk_dp->train_info.cable_plugged_in ||
 		    !mtk_dp_plug_state(mtk_dp)) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
 
 			mtk_dp_initialize_priv_data(mtk_dp);
 			mtk_dp_set_idle_pattern(mtk_dp, true);
 			if (mtk_dp->has_fec)
 				mtk_dp_fec_enable(mtk_dp, false);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 
 			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
 					   DP_PWR_STATE_BANDGAP_TPLL,
@@ -2107,6 +2747,18 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static void mtk_dp_update_plugged_status(struct mtk_dp *mtk_dp)
+{
+	bool connected, has_audio;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	connected = mtk_dp_plug_state(mtk_dp);
+	has_audio = drm_detect_monitor_audio(mtk_dp->edid);
+	if (mtk_dp->plugged_cb && mtk_dp->codec_dev)
+		mtk_dp->plugged_cb(mtk_dp->codec_dev, connected & has_audio);
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+}
+
 static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 {
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
@@ -2122,6 +2774,7 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 			ret = connector_status_connected;
 	}
 
+	mtk_dp_update_plugged_status(mtk_dp);
 	return ret;
 }
 
@@ -2308,6 +2961,7 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	mtk_dp->state = MTK_DP_STATE_IDLE;
 	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
 
@@ -2345,6 +2999,10 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
 		return;
 	}
 
+	mutex_lock(&mtk_dp->eld_lock);
+	memcpy(mtk_dp->connector_eld, mtk_dp->conn->eld, MAX_ELD_BYTES);
+	mutex_unlock(&mtk_dp->eld_lock);
+
 	mtk_dp->enabled = true;
 }
 
@@ -2491,6 +3149,104 @@ static void mtk_dp_debounce_timer(struct timer_list *t)
 	mtk_dp->need_debounce = true;
 }
 
+/*
+ * HDMI audio codec callbacks
+ */
+static int mtk_dp_audio_hw_params(struct device *dev, void *data,
+				  struct hdmi_codec_daifmt *daifmt,
+				  struct hdmi_codec_params *params)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct mtk_dp_audio_cfg cfg;
+
+	if (!mtk_dp->enabled) {
+		pr_err("%s, DP is not ready!\n", __func__);
+		return -ENODEV;
+	}
+
+	cfg.channels = params->cea.channels;
+	cfg.sample_rate = params->sample_rate;
+	cfg.word_length_bits = 24;
+
+	mtk_dp_audio_setup(mtk_dp, &cfg);
+
+	return 0;
+}
+
+static int mtk_dp_audio_startup(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, false);
+
+	return 0;
+}
+
+static void mtk_dp_audio_shutdown(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, true);
+}
+
+static int mtk_dp_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
+				size_t len)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp->enabled)
+		memcpy(buf, mtk_dp->connector_eld, len);
+	else
+		memset(buf, 0, len);
+
+	return 0;
+}
+
+static int mtk_dp_audio_hook_plugged_cb(struct device *dev, void *data,
+					hdmi_codec_plugged_cb fn,
+					struct device *codec_dev)
+{
+	struct mtk_dp *mtk_dp = data;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	mtk_dp->plugged_cb = fn;
+	mtk_dp->codec_dev = codec_dev;
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+
+	mtk_dp_update_plugged_status(mtk_dp);
+
+	return 0;
+}
+
+static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
+	.hw_params = mtk_dp_audio_hw_params,
+	.audio_startup = mtk_dp_audio_startup,
+	.audio_shutdown = mtk_dp_audio_shutdown,
+	.get_eld = mtk_dp_audio_get_eld,
+	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
+	.no_capture_mute = 1,
+};
+
+static int mtk_dp_register_audio_driver(struct device *dev)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct hdmi_codec_pdata codec_data = {
+		.ops = &mtk_dp_audio_codec_ops,
+		.max_i2s_channels = 8,
+		.i2s = 1,
+		.data = mtk_dp,
+	};
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO, &codec_data,
+					     sizeof(codec_data));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2534,9 +3290,21 @@ static int mtk_dp_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
 
 	mutex_init(&mtk_dp->dp_lock);
+	mutex_init(&mtk_dp->edid_lock);
+	mutex_init(&mtk_dp->eld_lock);
+	mutex_init(&mtk_dp->update_plugged_status_lock);
 
 	platform_set_drvdata(pdev, mtk_dp);
 
+	if (!mtk_dp_is_edp(mtk_dp)) {
+		ret = mtk_dp_register_audio_driver(dev);
+		if (ret) {
+			dev_err(dev, "Failed to register audio driver: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
 							PLATFORM_DEVID_AUTO,
 							&mtk_dp->regs,
@@ -2579,6 +3347,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 21/21] drm/mediatek: DP audio support for mt8195
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

This patch adds audio support to the DP driver for mt8195 with up to 8
channels.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 784 +++++++++++++++++++++++++++++-
 1 file changed, 777 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index c056bc3ca9f6..05da6565c7f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -108,9 +108,41 @@ enum mtk_dp_color_depth {
 	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
 };
 
+enum mtk_dp_sdp_type {
+	MTK_DP_SDP_NONE = 0x00,
+	MTK_DP_SDP_ACM = 0x01,
+	MTK_DP_SDP_ISRC = 0x02,
+	MTK_DP_SDP_AVI = 0x03,
+	MTK_DP_SDP_AUI = 0x04,
+	MTK_DP_SDP_SPD = 0x05,
+	MTK_DP_SDP_MPEG = 0x06,
+	MTK_DP_SDP_NTSC = 0x07,
+	MTK_DP_SDP_VSP = 0x08,
+	MTK_DP_SDP_VSC = 0x09,
+	MTK_DP_SDP_EXT = 0x0A,
+	MTK_DP_SDP_PPS0 = 0x0B,
+	MTK_DP_SDP_PPS1 = 0x0C,
+	MTK_DP_SDP_PPS2 = 0x0D,
+	MTK_DP_SDP_PPS3 = 0x0E,
+	MTK_DP_SDP_DRM = 0x10,
+	MTK_DP_SDP_MAX_NUM
+};
+
+struct mtk_dp_sdp_packet {
+	enum mtk_dp_sdp_type type;
+	struct dp_sdp sdp;
+};
+
+struct mtk_dp_audio_cfg {
+	int sample_rate;
+	int word_length_bits;
+	int channels;
+};
+
 struct mtk_dp_info {
 	enum mtk_dp_color_depth depth;
 	enum dp_pixelformat format;
+	struct mtk_dp_audio_cfg audio_caps;
 	struct mtk_dp_timings timings;
 };
 
@@ -148,10 +180,22 @@ struct mtk_dp {
 	struct clk *dp_tx_clk;
 
 	bool enabled;
+	bool audio_enable;
 
 	bool has_fec;
 	/* Protects the mtk_dp struct */
 	struct mutex dp_lock;
+	/* Protects the plugged_cb as it's used in both bridge ops and audio */
+	struct mutex update_plugged_status_lock;
+	/* Protects the eld data as it's used in both bridge ops and audio */
+	struct mutex eld_lock;
+	/* Protects edid as it is used in both bridge ops and IRQ handler */
+	struct mutex edid_lock;
+	struct edid *edid;
+
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
+	u8 connector_eld[MAX_ELD_BYTES];
 
 	struct drm_connector *conn;
 	bool need_debounce;
@@ -512,15 +556,363 @@ static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
 	return ret;
 }
 
+static int mtk_dp_audio_setup_channels(struct mtk_dp *mtk_dp,
+				       struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	u32 channel_enable_bits;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3324,
+				 AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX,
+			    AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(9), BIT(9));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_PRTY_REGEN_DP_ENC1_P0_MASK,
+			    AU_PRTY_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_CH_STS_REGEN_DP_ENC1_P0_MASK,
+			    AU_CH_STS_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK,
+			    AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	switch (cfg->channels) {
+	case 2:
+		channel_enable_bits = AUDIO_2CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_2CH_EN_DP_ENC0_P0_MASK;
+		break;
+	case 8:
+	default:
+		channel_enable_bits = AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_8CH_EN_DP_ENC0_P0_MASK;
+		break;
+	}
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+				 channel_enable_bits | AU_EN_DP_ENC0_P0_MASK,
+			   AUDIO_2CH_SEL_DP_ENC0_P0_MASK | AUDIO_2CH_EN_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_EN_DP_ENC0_P0_MASK | AU_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, 0, BIT(9));
+	if (ret)
+		return ret;
+
+	/* enable audio reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(0), BIT(0));
+
+	return ret;
+}
+
+static int mtk_dp_audio_channel_status_set(struct mtk_dp *mtk_dp,
+					   struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	struct snd_aes_iec958 iec = { 0 };
+
+	switch (cfg->sample_rate) {
+	case 32000:
+		iec.status[3] = IEC958_AES3_CON_FS_32000;
+		break;
+	case 44100:
+		iec.status[3] = IEC958_AES3_CON_FS_44100;
+		break;
+	case 48000:
+		iec.status[3] = IEC958_AES3_CON_FS_48000;
+		break;
+	case 88200:
+		iec.status[3] = IEC958_AES3_CON_FS_88200;
+		break;
+	case 96000:
+		iec.status[3] = IEC958_AES3_CON_FS_96000;
+		break;
+	case 192000:
+		iec.status[3] = IEC958_AES3_CON_FS_192000;
+		break;
+	default:
+		iec.status[3] = IEC958_AES3_CON_FS_NOTID;
+		break;
+	}
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16;
+		break;
+	case 20:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	case 24:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_24_20 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	default:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_NOTID;
+	}
+
+	/* IEC 60958 consumer channel status bits */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_308C,
+				 0,
+			   CH_STATUS_0_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3090,
+				 iec.status[3] << 8,
+			   CH_STATUS_1_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3094, iec.status[4],
+				 CH_STATUS_2_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_audio_sdp_asp_set_channels(struct mtk_dp *mtk_dp,
+					     int channels)
+{
+	if (channels != 2 && channels != 8)
+		channels = 8;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_312C,
+			   (channels - 1) << ASP_HB3_DP_ENC0_P0_SHIFT,
+			   ASP_HB2_DP_ENC0_P0_MASK | ASP_HB3_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_audio_set_divider(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK);
+}
+
 static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
 {
 	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
 		  HPD_DB_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+static int mtk_dp_sdp_trigger_packet(struct mtk_dp *mtk_dp,
+				     enum mtk_dp_sdp_type type)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, type,
+				 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, SDP_PACKET_W_DP_ENC1_P0,
+				 SDP_PACKET_W_DP_ENC1_P0);
+
+	return ret;
+}
+
+static void mtk_dp_sdp_set_data(struct mtk_dp *mtk_dp, u8 *data_bytes)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_ENC1_P0_3200, data_bytes, 0x10);
+}
+
+static void mtk_dp_sdp_set_header(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_sdp_type type,
+				  struct dp_sdp_header *header)
+{
+	u32 db_addr;
+
+	switch (type) {
+	case MTK_DP_SDP_DRM:
+		db_addr = MTK_DP_ENC0_P0_3138;
+		break;
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		db_addr = MTK_DP_ENC0_P0_3130;
+		break;
+	default:
+		db_addr = MTK_DP_ENC0_P0_30D8 + (type - MTK_DP_SDP_ACM) * 8;
+	}
+
+	mtk_dp_bulk_16bit_write(mtk_dp, db_addr, (u8 *)header, 4);
+}
+
+static const u32 mtk_dp_sdp_type_to_reg[MTK_DP_SDP_MAX_NUM] = {
+	/* MTK_DP_SDP_NONE => */ 0x0,
+	/* MTK_DP_SDP_ACM  => */ MTK_DP_ENC0_P0_30B4,
+	/* MTK_DP_SDP_ISRC => */ MTK_DP_ENC0_P0_30B4 + 1,
+	/* MTK_DP_SDP_AVI  => */ MTK_DP_ENC0_P0_30A4 + 1,
+	/* MTK_DP_SDP_AUI  => */ MTK_DP_ENC0_P0_30A8,
+	/* MTK_DP_SDP_SPD  => */ MTK_DP_ENC0_P0_30A8 + 1,
+	/* MTK_DP_SDP_MPEG => */ MTK_DP_ENC0_P0_30AC,
+	/* MTK_DP_SDP_NTSC => */ MTK_DP_ENC0_P0_30AC + 1,
+	/* MTK_DP_SDP_VSP  => */ MTK_DP_ENC0_P0_30B0,
+	/* MTK_DP_SDP_VSC  => */ MTK_DP_ENC0_P0_30B8,
+	/* MTK_DP_SDP_EXT  => */ MTK_DP_ENC0_P0_30B0 + 1,
+	/* MTK_DP_SDP_PPS0 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS1 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS2 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS3 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_DRM  => */ MTK_DP_ENC0_P0_31DC,
+};
+
+static int mtk_dp_disable_sdp(struct mtk_dp *mtk_dp, enum mtk_dp_sdp_type type)
+{
+	if (type == MTK_DP_SDP_NONE)
+		return -EINVAL;
+
+	/* Disable periodic send */
+	return mtk_dp_update_bits(mtk_dp, mtk_dp_sdp_type_to_reg[type] & 0xfffc, 0,
+			   0xFF << ((mtk_dp_sdp_type_to_reg[type] & 3) * 8));
+}
+
+static int mtk_dp_setup_sdp(struct mtk_dp *mtk_dp,
+			    struct mtk_dp_sdp_packet *packet)
+{
+	int ret = -EINVAL;
+
+	mtk_dp_sdp_set_data(mtk_dp, packet->sdp.db);
+	mtk_dp_sdp_set_header(mtk_dp, packet->type, &packet->sdp.sdp_header);
+
+	mtk_dp_disable_sdp(mtk_dp, packet->type);
+
+	switch (packet->type) {
+	case MTK_DP_SDP_NONE:
+		break;
+	case MTK_DP_SDP_ISRC:
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+					 ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+					 SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+					 ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_DRM:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31DC,
+					 5 << HDR0_CFG_DP_ENC0_P0_SHIFT,
+					 HDR0_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+				   ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+					   ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+				   SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+				   ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_ACM:
+	case MTK_DP_SDP_AVI:
+	case MTK_DP_SDP_AUI:
+	case MTK_DP_SDP_SPD:
+	case MTK_DP_SDP_MPEG:
+	case MTK_DP_SDP_NTSC:
+	case MTK_DP_SDP_VSP:
+	case MTK_DP_SDP_VSC:
+	case MTK_DP_SDP_EXT:
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		/* Enable periodic sending */
+		ret = mtk_dp_update_bits(mtk_dp,
+					 mtk_dp_sdp_type_to_reg[packet->type] & 0xfffc,
+					 0x05 << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8),
+					 0xff << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8));
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int mtk_dp_sdp_vsc_ext_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A0, 0,
+				 BIT(7) | BIT(8) | BIT(12));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_328C, 0, BIT(7));
+
+	return ret;
+}
+
+static int mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
 {
-	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+	return mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
 		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
@@ -1244,20 +1636,71 @@ static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
 			   DP_SCR_EN_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+static int mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 {
+	int ret;
 	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
 
 	if (enable)
 		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
-			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
-			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+				 VIDEO_MUTE_SEL_DP_ENC0_P0_MASK | VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	if (ret)
+		return ret;
 
 	if (mtk_dp_is_edp(mtk_dp))
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
 	else
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
+
+	return 0;
+}
+
+static int mtk_dp_audio_mute(struct mtk_dp *mtk_dp, bool mute)
+{
+	int ret;
+
+	if (mute) {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030,
+				   BIT(VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT) |
+				   BIT(VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT),
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088, 0,
+					 AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030, 0,
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+					 BIT(AU_EN_DP_ENC0_P0_SHIFT),
+				   AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Send one every two frames */
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0x0F,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+	}
+
+	return ret;
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -1327,6 +1770,83 @@ static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
 	mtk_dp->info.timings.frame_rate = 60;
 
 	mtk_dp->has_fec = false;
+	mtk_dp->audio_enable = false;
+}
+
+static int mtk_dp_sdp_set_down_cnt_init(struct mtk_dp *mtk_dp,
+					u32 sram_read_start)
+{
+	u32 sdp_down_cnt_init = 0;
+	u32 dc_offset;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.pix_rate_khz > 0)
+		sdp_down_cnt_init = sram_read_start *
+				    mtk_dp->train_info.link_rate * 2700 * 8 /
+				    (timings->pix_rate_khz * 4);
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x1A ?
+						  sdp_down_cnt_init :
+						  0x1A; /* 26 */
+		break;
+	case 2:
+		/* case for LowResolution && High Audio Sample Rate */
+		dc_offset = mode.vtotal <= 525 ? 0x04 : 0x00;
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x10 ?
+						  sdp_down_cnt_init :
+						  0x10 + dc_offset; /* 20 or 16 */
+		break;
+	case 4:
+	default:
+		sdp_down_cnt_init =
+			sdp_down_cnt_init > 0x06 ? sdp_down_cnt_init : 0x06; /*6 */
+		break;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+			   sdp_down_cnt_init
+				   << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			   SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_sdp_set_down_cnt_init_in_hblank(struct mtk_dp *mtk_dp)
+{
+	int pix_clk_mhz;
+	u32 dc_offset;
+	u32 spd_down_cnt_init = 0;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	pix_clk_mhz = mtk_dp->info.format == DP_PIXELFORMAT_YUV420 ?
+				    mtk_dp->info.timings.pix_rate_khz / 2000 :
+				    mtk_dp->info.timings.pix_rate_khz / 1000;
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		spd_down_cnt_init = 0x20;
+		break;
+	case 2:
+		dc_offset = (mode.vtotal <= 525) ? 0x14 : 0x00;
+		spd_down_cnt_init = 0x18 + dc_offset;
+		break;
+	case 4:
+	default:
+		dc_offset = (mode.vtotal <= 525) ? 0x08 : 0x00;
+		if (pix_clk_mhz > mtk_dp->train_info.link_rate * 27)
+			spd_down_cnt_init = 0x8;
+		else
+			spd_down_cnt_init = 0x10 + dc_offset;
+		break;
+	}
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364, spd_down_cnt_init,
+			   SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
 }
 
 static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
@@ -1343,6 +1863,8 @@ static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
 	}
 
 	mtk_dp_setup_encoder(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init_in_hblank(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init(mtk_dp, sram_read_start);
 }
 
 static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
@@ -1420,6 +1942,17 @@ static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
 	return 0;
 }
 
+static void mtk_dp_sdp_stop_sending(struct mtk_dp *mtk_dp)
+{
+	u8 packet_type;
+
+	for (packet_type = MTK_DP_SDP_ACM; packet_type < MTK_DP_SDP_MAX_NUM;
+	     packet_type++)
+		mtk_dp_disable_sdp(mtk_dp, packet_type);
+
+	mtk_dp_sdp_vsc_ext_disable(mtk_dp);
+}
+
 static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
 					  u8 dpcd_adjust_req[2])
 {
@@ -1725,6 +2258,52 @@ static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
 	return true;
 }
 
+static int mtk_dp_edid_parse_audio_capabilities(struct mtk_dp *mtk_dp,
+						struct mtk_dp_audio_cfg *cfg)
+{
+	struct cea_sad *sads;
+	int sad_count;
+	int i;
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->edid_lock);
+	if (!mtk_dp->edid) {
+		mutex_unlock(&mtk_dp->edid_lock);
+		dev_err(mtk_dp->dev, "EDID not found!\n");
+		return -EINVAL;
+	}
+
+	sad_count = drm_edid_to_sad(mtk_dp->edid, &sads);
+	mutex_unlock(&mtk_dp->edid_lock);
+	if (sad_count <= 0) {
+		drm_info(mtk_dp->drm_dev, "The SADs is NULL\n");
+		return 0;
+	}
+
+	for (i = 0; i < sad_count; i++) {
+		int sample_rate;
+		int word_length;
+		/* Only PCM supported at the moment */
+		if (sads[i].format != HDMI_AUDIO_CODING_TYPE_PCM)
+			continue;
+
+		sample_rate = drm_cea_sad_get_sample_rate(&sads[i]);
+		word_length =
+			drm_cea_sad_get_uncompressed_word_length(&sads[i]);
+		if (sample_rate <= 0 || word_length <= 0)
+			continue;
+
+		cfg->channels = sads[i].channels;
+		cfg->word_length_bits = word_length;
+		cfg->sample_rate = sample_rate;
+		ret = 1;
+		break;
+	}
+	kfree(sads);
+
+	return ret;
+}
+
 static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
 {
 	phy_reset(mtk_dp->phy);
@@ -1830,6 +2409,48 @@ static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
 	}
 }
 
+static void mtk_dp_audio_sdp_setup(struct mtk_dp *mtk_dp,
+				   struct mtk_dp_audio_cfg *cfg)
+{
+	struct mtk_dp_sdp_packet packet;
+	struct hdmi_audio_infoframe frame;
+
+	hdmi_audio_infoframe_init(&frame);
+	frame.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;
+	frame.channels = cfg->channels;
+	frame.sample_frequency = cfg->sample_rate;
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		break;
+	case 20:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
+		break;
+	case 24:
+	default:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
+		break;
+	}
+
+	packet.type = MTK_DP_SDP_AUI;
+	hdmi_audio_infoframe_pack_for_dp(&frame, &packet.sdp,
+					 MTK_DP_DP_VERSION_11);
+
+	mtk_dp_audio_sdp_asp_set_channels(mtk_dp, cfg->channels);
+	mtk_dp_setup_sdp(mtk_dp, &packet);
+}
+
+static void mtk_dp_audio_setup(struct mtk_dp *mtk_dp,
+			       struct mtk_dp_audio_cfg *cfg)
+{
+	mtk_dp_audio_sdp_setup(mtk_dp, cfg);
+	mtk_dp_audio_channel_status_set(mtk_dp, cfg);
+
+	mtk_dp_audio_setup_channels(mtk_dp, cfg);
+	mtk_dp_audio_set_divider(mtk_dp);
+}
+
 static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
 {
 	mtk_dp_mn_overwrite_disable(mtk_dp);
@@ -1845,6 +2466,7 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 	switch (mtk_dp->state) {
 	case MTK_DP_STATE_INITIAL:
 		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp_audio_mute(mtk_dp, true);
 		mtk_dp->state = MTK_DP_STATE_IDLE;
 		break;
 
@@ -1857,12 +2479,19 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 		mtk_dp_video_config(mtk_dp);
 		mtk_dp_video_enable(mtk_dp, true);
 
+		if (mtk_dp->audio_enable) {
+			mtk_dp_audio_setup(mtk_dp, &mtk_dp->info.audio_caps);
+			mtk_dp_audio_mute(mtk_dp, false);
+		}
+
 		mtk_dp->state = MTK_DP_STATE_NORMAL;
 		break;
 
 	case MTK_DP_STATE_NORMAL:
 		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 			mtk_dp->state = MTK_DP_STATE_IDLE;
 		}
 		break;
@@ -1901,7 +2530,15 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			}
 			break;
 
-		case MTK_DP_TRAIN_STATE_CHECKEDID:
+		case MTK_DP_TRAIN_STATE_CHECKEDID: {
+			int caps_found = mtk_dp_edid_parse_audio_capabilities(mtk_dp,
+				&mtk_dp->info.audio_caps);
+			mtk_dp->audio_enable = caps_found > 0;
+			if (!mtk_dp->audio_enable)
+				memset(&mtk_dp->info.audio_caps, 0,
+				       sizeof(mtk_dp->info.audio_caps));
+		}
+
 			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
 			break;
 
@@ -1914,6 +2551,7 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			ret = mtk_dp_train_start(mtk_dp);
 			if (ret == 0) {
 				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp_audio_mute(mtk_dp, true);
 				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
 				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
 			} else if (ret != -EAGAIN) {
@@ -1988,11 +2626,13 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 		if (!mtk_dp->train_info.cable_plugged_in ||
 		    !mtk_dp_plug_state(mtk_dp)) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
 
 			mtk_dp_initialize_priv_data(mtk_dp);
 			mtk_dp_set_idle_pattern(mtk_dp, true);
 			if (mtk_dp->has_fec)
 				mtk_dp_fec_enable(mtk_dp, false);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 
 			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
 					   DP_PWR_STATE_BANDGAP_TPLL,
@@ -2107,6 +2747,18 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static void mtk_dp_update_plugged_status(struct mtk_dp *mtk_dp)
+{
+	bool connected, has_audio;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	connected = mtk_dp_plug_state(mtk_dp);
+	has_audio = drm_detect_monitor_audio(mtk_dp->edid);
+	if (mtk_dp->plugged_cb && mtk_dp->codec_dev)
+		mtk_dp->plugged_cb(mtk_dp->codec_dev, connected & has_audio);
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+}
+
 static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 {
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
@@ -2122,6 +2774,7 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 			ret = connector_status_connected;
 	}
 
+	mtk_dp_update_plugged_status(mtk_dp);
 	return ret;
 }
 
@@ -2308,6 +2961,7 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	mtk_dp->state = MTK_DP_STATE_IDLE;
 	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
 
@@ -2345,6 +2999,10 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
 		return;
 	}
 
+	mutex_lock(&mtk_dp->eld_lock);
+	memcpy(mtk_dp->connector_eld, mtk_dp->conn->eld, MAX_ELD_BYTES);
+	mutex_unlock(&mtk_dp->eld_lock);
+
 	mtk_dp->enabled = true;
 }
 
@@ -2491,6 +3149,104 @@ static void mtk_dp_debounce_timer(struct timer_list *t)
 	mtk_dp->need_debounce = true;
 }
 
+/*
+ * HDMI audio codec callbacks
+ */
+static int mtk_dp_audio_hw_params(struct device *dev, void *data,
+				  struct hdmi_codec_daifmt *daifmt,
+				  struct hdmi_codec_params *params)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct mtk_dp_audio_cfg cfg;
+
+	if (!mtk_dp->enabled) {
+		pr_err("%s, DP is not ready!\n", __func__);
+		return -ENODEV;
+	}
+
+	cfg.channels = params->cea.channels;
+	cfg.sample_rate = params->sample_rate;
+	cfg.word_length_bits = 24;
+
+	mtk_dp_audio_setup(mtk_dp, &cfg);
+
+	return 0;
+}
+
+static int mtk_dp_audio_startup(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, false);
+
+	return 0;
+}
+
+static void mtk_dp_audio_shutdown(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, true);
+}
+
+static int mtk_dp_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
+				size_t len)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp->enabled)
+		memcpy(buf, mtk_dp->connector_eld, len);
+	else
+		memset(buf, 0, len);
+
+	return 0;
+}
+
+static int mtk_dp_audio_hook_plugged_cb(struct device *dev, void *data,
+					hdmi_codec_plugged_cb fn,
+					struct device *codec_dev)
+{
+	struct mtk_dp *mtk_dp = data;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	mtk_dp->plugged_cb = fn;
+	mtk_dp->codec_dev = codec_dev;
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+
+	mtk_dp_update_plugged_status(mtk_dp);
+
+	return 0;
+}
+
+static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
+	.hw_params = mtk_dp_audio_hw_params,
+	.audio_startup = mtk_dp_audio_startup,
+	.audio_shutdown = mtk_dp_audio_shutdown,
+	.get_eld = mtk_dp_audio_get_eld,
+	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
+	.no_capture_mute = 1,
+};
+
+static int mtk_dp_register_audio_driver(struct device *dev)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct hdmi_codec_pdata codec_data = {
+		.ops = &mtk_dp_audio_codec_ops,
+		.max_i2s_channels = 8,
+		.i2s = 1,
+		.data = mtk_dp,
+	};
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO, &codec_data,
+					     sizeof(codec_data));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2534,9 +3290,21 @@ static int mtk_dp_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
 
 	mutex_init(&mtk_dp->dp_lock);
+	mutex_init(&mtk_dp->edid_lock);
+	mutex_init(&mtk_dp->eld_lock);
+	mutex_init(&mtk_dp->update_plugged_status_lock);
 
 	platform_set_drvdata(pdev, mtk_dp);
 
+	if (!mtk_dp_is_edp(mtk_dp)) {
+		ret = mtk_dp_register_audio_driver(dev);
+		if (ret) {
+			dev_err(dev, "Failed to register audio driver: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
 							PLATFORM_DEVID_AUTO,
 							&mtk_dp->regs,
@@ -2579,6 +3347,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
-- 
2.35.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 21/21] drm/mediatek: DP audio support for mt8195
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

This patch adds audio support to the DP driver for mt8195 with up to 8
channels.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 784 +++++++++++++++++++++++++++++-
 1 file changed, 777 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index c056bc3ca9f6..05da6565c7f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -108,9 +108,41 @@ enum mtk_dp_color_depth {
 	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
 };
 
+enum mtk_dp_sdp_type {
+	MTK_DP_SDP_NONE = 0x00,
+	MTK_DP_SDP_ACM = 0x01,
+	MTK_DP_SDP_ISRC = 0x02,
+	MTK_DP_SDP_AVI = 0x03,
+	MTK_DP_SDP_AUI = 0x04,
+	MTK_DP_SDP_SPD = 0x05,
+	MTK_DP_SDP_MPEG = 0x06,
+	MTK_DP_SDP_NTSC = 0x07,
+	MTK_DP_SDP_VSP = 0x08,
+	MTK_DP_SDP_VSC = 0x09,
+	MTK_DP_SDP_EXT = 0x0A,
+	MTK_DP_SDP_PPS0 = 0x0B,
+	MTK_DP_SDP_PPS1 = 0x0C,
+	MTK_DP_SDP_PPS2 = 0x0D,
+	MTK_DP_SDP_PPS3 = 0x0E,
+	MTK_DP_SDP_DRM = 0x10,
+	MTK_DP_SDP_MAX_NUM
+};
+
+struct mtk_dp_sdp_packet {
+	enum mtk_dp_sdp_type type;
+	struct dp_sdp sdp;
+};
+
+struct mtk_dp_audio_cfg {
+	int sample_rate;
+	int word_length_bits;
+	int channels;
+};
+
 struct mtk_dp_info {
 	enum mtk_dp_color_depth depth;
 	enum dp_pixelformat format;
+	struct mtk_dp_audio_cfg audio_caps;
 	struct mtk_dp_timings timings;
 };
 
@@ -148,10 +180,22 @@ struct mtk_dp {
 	struct clk *dp_tx_clk;
 
 	bool enabled;
+	bool audio_enable;
 
 	bool has_fec;
 	/* Protects the mtk_dp struct */
 	struct mutex dp_lock;
+	/* Protects the plugged_cb as it's used in both bridge ops and audio */
+	struct mutex update_plugged_status_lock;
+	/* Protects the eld data as it's used in both bridge ops and audio */
+	struct mutex eld_lock;
+	/* Protects edid as it is used in both bridge ops and IRQ handler */
+	struct mutex edid_lock;
+	struct edid *edid;
+
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
+	u8 connector_eld[MAX_ELD_BYTES];
 
 	struct drm_connector *conn;
 	bool need_debounce;
@@ -512,15 +556,363 @@ static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
 	return ret;
 }
 
+static int mtk_dp_audio_setup_channels(struct mtk_dp *mtk_dp,
+				       struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	u32 channel_enable_bits;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3324,
+				 AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX,
+			    AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(9), BIT(9));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_PRTY_REGEN_DP_ENC1_P0_MASK,
+			    AU_PRTY_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_CH_STS_REGEN_DP_ENC1_P0_MASK,
+			    AU_CH_STS_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK,
+			    AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	switch (cfg->channels) {
+	case 2:
+		channel_enable_bits = AUDIO_2CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_2CH_EN_DP_ENC0_P0_MASK;
+		break;
+	case 8:
+	default:
+		channel_enable_bits = AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_8CH_EN_DP_ENC0_P0_MASK;
+		break;
+	}
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+				 channel_enable_bits | AU_EN_DP_ENC0_P0_MASK,
+			   AUDIO_2CH_SEL_DP_ENC0_P0_MASK | AUDIO_2CH_EN_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_EN_DP_ENC0_P0_MASK | AU_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, 0, BIT(9));
+	if (ret)
+		return ret;
+
+	/* enable audio reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(0), BIT(0));
+
+	return ret;
+}
+
+static int mtk_dp_audio_channel_status_set(struct mtk_dp *mtk_dp,
+					   struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	struct snd_aes_iec958 iec = { 0 };
+
+	switch (cfg->sample_rate) {
+	case 32000:
+		iec.status[3] = IEC958_AES3_CON_FS_32000;
+		break;
+	case 44100:
+		iec.status[3] = IEC958_AES3_CON_FS_44100;
+		break;
+	case 48000:
+		iec.status[3] = IEC958_AES3_CON_FS_48000;
+		break;
+	case 88200:
+		iec.status[3] = IEC958_AES3_CON_FS_88200;
+		break;
+	case 96000:
+		iec.status[3] = IEC958_AES3_CON_FS_96000;
+		break;
+	case 192000:
+		iec.status[3] = IEC958_AES3_CON_FS_192000;
+		break;
+	default:
+		iec.status[3] = IEC958_AES3_CON_FS_NOTID;
+		break;
+	}
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16;
+		break;
+	case 20:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	case 24:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_24_20 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	default:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_NOTID;
+	}
+
+	/* IEC 60958 consumer channel status bits */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_308C,
+				 0,
+			   CH_STATUS_0_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3090,
+				 iec.status[3] << 8,
+			   CH_STATUS_1_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3094, iec.status[4],
+				 CH_STATUS_2_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_audio_sdp_asp_set_channels(struct mtk_dp *mtk_dp,
+					     int channels)
+{
+	if (channels != 2 && channels != 8)
+		channels = 8;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_312C,
+			   (channels - 1) << ASP_HB3_DP_ENC0_P0_SHIFT,
+			   ASP_HB2_DP_ENC0_P0_MASK | ASP_HB3_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_audio_set_divider(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK);
+}
+
 static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
 {
 	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
 		  HPD_DB_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+static int mtk_dp_sdp_trigger_packet(struct mtk_dp *mtk_dp,
+				     enum mtk_dp_sdp_type type)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, type,
+				 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, SDP_PACKET_W_DP_ENC1_P0,
+				 SDP_PACKET_W_DP_ENC1_P0);
+
+	return ret;
+}
+
+static void mtk_dp_sdp_set_data(struct mtk_dp *mtk_dp, u8 *data_bytes)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_ENC1_P0_3200, data_bytes, 0x10);
+}
+
+static void mtk_dp_sdp_set_header(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_sdp_type type,
+				  struct dp_sdp_header *header)
+{
+	u32 db_addr;
+
+	switch (type) {
+	case MTK_DP_SDP_DRM:
+		db_addr = MTK_DP_ENC0_P0_3138;
+		break;
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		db_addr = MTK_DP_ENC0_P0_3130;
+		break;
+	default:
+		db_addr = MTK_DP_ENC0_P0_30D8 + (type - MTK_DP_SDP_ACM) * 8;
+	}
+
+	mtk_dp_bulk_16bit_write(mtk_dp, db_addr, (u8 *)header, 4);
+}
+
+static const u32 mtk_dp_sdp_type_to_reg[MTK_DP_SDP_MAX_NUM] = {
+	/* MTK_DP_SDP_NONE => */ 0x0,
+	/* MTK_DP_SDP_ACM  => */ MTK_DP_ENC0_P0_30B4,
+	/* MTK_DP_SDP_ISRC => */ MTK_DP_ENC0_P0_30B4 + 1,
+	/* MTK_DP_SDP_AVI  => */ MTK_DP_ENC0_P0_30A4 + 1,
+	/* MTK_DP_SDP_AUI  => */ MTK_DP_ENC0_P0_30A8,
+	/* MTK_DP_SDP_SPD  => */ MTK_DP_ENC0_P0_30A8 + 1,
+	/* MTK_DP_SDP_MPEG => */ MTK_DP_ENC0_P0_30AC,
+	/* MTK_DP_SDP_NTSC => */ MTK_DP_ENC0_P0_30AC + 1,
+	/* MTK_DP_SDP_VSP  => */ MTK_DP_ENC0_P0_30B0,
+	/* MTK_DP_SDP_VSC  => */ MTK_DP_ENC0_P0_30B8,
+	/* MTK_DP_SDP_EXT  => */ MTK_DP_ENC0_P0_30B0 + 1,
+	/* MTK_DP_SDP_PPS0 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS1 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS2 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS3 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_DRM  => */ MTK_DP_ENC0_P0_31DC,
+};
+
+static int mtk_dp_disable_sdp(struct mtk_dp *mtk_dp, enum mtk_dp_sdp_type type)
+{
+	if (type == MTK_DP_SDP_NONE)
+		return -EINVAL;
+
+	/* Disable periodic send */
+	return mtk_dp_update_bits(mtk_dp, mtk_dp_sdp_type_to_reg[type] & 0xfffc, 0,
+			   0xFF << ((mtk_dp_sdp_type_to_reg[type] & 3) * 8));
+}
+
+static int mtk_dp_setup_sdp(struct mtk_dp *mtk_dp,
+			    struct mtk_dp_sdp_packet *packet)
+{
+	int ret = -EINVAL;
+
+	mtk_dp_sdp_set_data(mtk_dp, packet->sdp.db);
+	mtk_dp_sdp_set_header(mtk_dp, packet->type, &packet->sdp.sdp_header);
+
+	mtk_dp_disable_sdp(mtk_dp, packet->type);
+
+	switch (packet->type) {
+	case MTK_DP_SDP_NONE:
+		break;
+	case MTK_DP_SDP_ISRC:
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+					 ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+					 SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+					 ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_DRM:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31DC,
+					 5 << HDR0_CFG_DP_ENC0_P0_SHIFT,
+					 HDR0_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+				   ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+					   ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+				   SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+				   ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_ACM:
+	case MTK_DP_SDP_AVI:
+	case MTK_DP_SDP_AUI:
+	case MTK_DP_SDP_SPD:
+	case MTK_DP_SDP_MPEG:
+	case MTK_DP_SDP_NTSC:
+	case MTK_DP_SDP_VSP:
+	case MTK_DP_SDP_VSC:
+	case MTK_DP_SDP_EXT:
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		/* Enable periodic sending */
+		ret = mtk_dp_update_bits(mtk_dp,
+					 mtk_dp_sdp_type_to_reg[packet->type] & 0xfffc,
+					 0x05 << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8),
+					 0xff << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8));
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int mtk_dp_sdp_vsc_ext_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A0, 0,
+				 BIT(7) | BIT(8) | BIT(12));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_328C, 0, BIT(7));
+
+	return ret;
+}
+
+static int mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
 {
-	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+	return mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
 		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
@@ -1244,20 +1636,71 @@ static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
 			   DP_SCR_EN_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+static int mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 {
+	int ret;
 	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
 
 	if (enable)
 		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
-			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
-			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+				 VIDEO_MUTE_SEL_DP_ENC0_P0_MASK | VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	if (ret)
+		return ret;
 
 	if (mtk_dp_is_edp(mtk_dp))
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
 	else
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
+
+	return 0;
+}
+
+static int mtk_dp_audio_mute(struct mtk_dp *mtk_dp, bool mute)
+{
+	int ret;
+
+	if (mute) {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030,
+				   BIT(VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT) |
+				   BIT(VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT),
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088, 0,
+					 AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030, 0,
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+					 BIT(AU_EN_DP_ENC0_P0_SHIFT),
+				   AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Send one every two frames */
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0x0F,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+	}
+
+	return ret;
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -1327,6 +1770,83 @@ static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
 	mtk_dp->info.timings.frame_rate = 60;
 
 	mtk_dp->has_fec = false;
+	mtk_dp->audio_enable = false;
+}
+
+static int mtk_dp_sdp_set_down_cnt_init(struct mtk_dp *mtk_dp,
+					u32 sram_read_start)
+{
+	u32 sdp_down_cnt_init = 0;
+	u32 dc_offset;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.pix_rate_khz > 0)
+		sdp_down_cnt_init = sram_read_start *
+				    mtk_dp->train_info.link_rate * 2700 * 8 /
+				    (timings->pix_rate_khz * 4);
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x1A ?
+						  sdp_down_cnt_init :
+						  0x1A; /* 26 */
+		break;
+	case 2:
+		/* case for LowResolution && High Audio Sample Rate */
+		dc_offset = mode.vtotal <= 525 ? 0x04 : 0x00;
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x10 ?
+						  sdp_down_cnt_init :
+						  0x10 + dc_offset; /* 20 or 16 */
+		break;
+	case 4:
+	default:
+		sdp_down_cnt_init =
+			sdp_down_cnt_init > 0x06 ? sdp_down_cnt_init : 0x06; /*6 */
+		break;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+			   sdp_down_cnt_init
+				   << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			   SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_sdp_set_down_cnt_init_in_hblank(struct mtk_dp *mtk_dp)
+{
+	int pix_clk_mhz;
+	u32 dc_offset;
+	u32 spd_down_cnt_init = 0;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	pix_clk_mhz = mtk_dp->info.format == DP_PIXELFORMAT_YUV420 ?
+				    mtk_dp->info.timings.pix_rate_khz / 2000 :
+				    mtk_dp->info.timings.pix_rate_khz / 1000;
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		spd_down_cnt_init = 0x20;
+		break;
+	case 2:
+		dc_offset = (mode.vtotal <= 525) ? 0x14 : 0x00;
+		spd_down_cnt_init = 0x18 + dc_offset;
+		break;
+	case 4:
+	default:
+		dc_offset = (mode.vtotal <= 525) ? 0x08 : 0x00;
+		if (pix_clk_mhz > mtk_dp->train_info.link_rate * 27)
+			spd_down_cnt_init = 0x8;
+		else
+			spd_down_cnt_init = 0x10 + dc_offset;
+		break;
+	}
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364, spd_down_cnt_init,
+			   SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
 }
 
 static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
@@ -1343,6 +1863,8 @@ static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
 	}
 
 	mtk_dp_setup_encoder(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init_in_hblank(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init(mtk_dp, sram_read_start);
 }
 
 static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
@@ -1420,6 +1942,17 @@ static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
 	return 0;
 }
 
+static void mtk_dp_sdp_stop_sending(struct mtk_dp *mtk_dp)
+{
+	u8 packet_type;
+
+	for (packet_type = MTK_DP_SDP_ACM; packet_type < MTK_DP_SDP_MAX_NUM;
+	     packet_type++)
+		mtk_dp_disable_sdp(mtk_dp, packet_type);
+
+	mtk_dp_sdp_vsc_ext_disable(mtk_dp);
+}
+
 static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
 					  u8 dpcd_adjust_req[2])
 {
@@ -1725,6 +2258,52 @@ static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
 	return true;
 }
 
+static int mtk_dp_edid_parse_audio_capabilities(struct mtk_dp *mtk_dp,
+						struct mtk_dp_audio_cfg *cfg)
+{
+	struct cea_sad *sads;
+	int sad_count;
+	int i;
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->edid_lock);
+	if (!mtk_dp->edid) {
+		mutex_unlock(&mtk_dp->edid_lock);
+		dev_err(mtk_dp->dev, "EDID not found!\n");
+		return -EINVAL;
+	}
+
+	sad_count = drm_edid_to_sad(mtk_dp->edid, &sads);
+	mutex_unlock(&mtk_dp->edid_lock);
+	if (sad_count <= 0) {
+		drm_info(mtk_dp->drm_dev, "The SADs is NULL\n");
+		return 0;
+	}
+
+	for (i = 0; i < sad_count; i++) {
+		int sample_rate;
+		int word_length;
+		/* Only PCM supported at the moment */
+		if (sads[i].format != HDMI_AUDIO_CODING_TYPE_PCM)
+			continue;
+
+		sample_rate = drm_cea_sad_get_sample_rate(&sads[i]);
+		word_length =
+			drm_cea_sad_get_uncompressed_word_length(&sads[i]);
+		if (sample_rate <= 0 || word_length <= 0)
+			continue;
+
+		cfg->channels = sads[i].channels;
+		cfg->word_length_bits = word_length;
+		cfg->sample_rate = sample_rate;
+		ret = 1;
+		break;
+	}
+	kfree(sads);
+
+	return ret;
+}
+
 static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
 {
 	phy_reset(mtk_dp->phy);
@@ -1830,6 +2409,48 @@ static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
 	}
 }
 
+static void mtk_dp_audio_sdp_setup(struct mtk_dp *mtk_dp,
+				   struct mtk_dp_audio_cfg *cfg)
+{
+	struct mtk_dp_sdp_packet packet;
+	struct hdmi_audio_infoframe frame;
+
+	hdmi_audio_infoframe_init(&frame);
+	frame.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;
+	frame.channels = cfg->channels;
+	frame.sample_frequency = cfg->sample_rate;
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		break;
+	case 20:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
+		break;
+	case 24:
+	default:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
+		break;
+	}
+
+	packet.type = MTK_DP_SDP_AUI;
+	hdmi_audio_infoframe_pack_for_dp(&frame, &packet.sdp,
+					 MTK_DP_DP_VERSION_11);
+
+	mtk_dp_audio_sdp_asp_set_channels(mtk_dp, cfg->channels);
+	mtk_dp_setup_sdp(mtk_dp, &packet);
+}
+
+static void mtk_dp_audio_setup(struct mtk_dp *mtk_dp,
+			       struct mtk_dp_audio_cfg *cfg)
+{
+	mtk_dp_audio_sdp_setup(mtk_dp, cfg);
+	mtk_dp_audio_channel_status_set(mtk_dp, cfg);
+
+	mtk_dp_audio_setup_channels(mtk_dp, cfg);
+	mtk_dp_audio_set_divider(mtk_dp);
+}
+
 static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
 {
 	mtk_dp_mn_overwrite_disable(mtk_dp);
@@ -1845,6 +2466,7 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 	switch (mtk_dp->state) {
 	case MTK_DP_STATE_INITIAL:
 		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp_audio_mute(mtk_dp, true);
 		mtk_dp->state = MTK_DP_STATE_IDLE;
 		break;
 
@@ -1857,12 +2479,19 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 		mtk_dp_video_config(mtk_dp);
 		mtk_dp_video_enable(mtk_dp, true);
 
+		if (mtk_dp->audio_enable) {
+			mtk_dp_audio_setup(mtk_dp, &mtk_dp->info.audio_caps);
+			mtk_dp_audio_mute(mtk_dp, false);
+		}
+
 		mtk_dp->state = MTK_DP_STATE_NORMAL;
 		break;
 
 	case MTK_DP_STATE_NORMAL:
 		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 			mtk_dp->state = MTK_DP_STATE_IDLE;
 		}
 		break;
@@ -1901,7 +2530,15 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			}
 			break;
 
-		case MTK_DP_TRAIN_STATE_CHECKEDID:
+		case MTK_DP_TRAIN_STATE_CHECKEDID: {
+			int caps_found = mtk_dp_edid_parse_audio_capabilities(mtk_dp,
+				&mtk_dp->info.audio_caps);
+			mtk_dp->audio_enable = caps_found > 0;
+			if (!mtk_dp->audio_enable)
+				memset(&mtk_dp->info.audio_caps, 0,
+				       sizeof(mtk_dp->info.audio_caps));
+		}
+
 			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
 			break;
 
@@ -1914,6 +2551,7 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			ret = mtk_dp_train_start(mtk_dp);
 			if (ret == 0) {
 				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp_audio_mute(mtk_dp, true);
 				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
 				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
 			} else if (ret != -EAGAIN) {
@@ -1988,11 +2626,13 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 		if (!mtk_dp->train_info.cable_plugged_in ||
 		    !mtk_dp_plug_state(mtk_dp)) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
 
 			mtk_dp_initialize_priv_data(mtk_dp);
 			mtk_dp_set_idle_pattern(mtk_dp, true);
 			if (mtk_dp->has_fec)
 				mtk_dp_fec_enable(mtk_dp, false);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 
 			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
 					   DP_PWR_STATE_BANDGAP_TPLL,
@@ -2107,6 +2747,18 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static void mtk_dp_update_plugged_status(struct mtk_dp *mtk_dp)
+{
+	bool connected, has_audio;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	connected = mtk_dp_plug_state(mtk_dp);
+	has_audio = drm_detect_monitor_audio(mtk_dp->edid);
+	if (mtk_dp->plugged_cb && mtk_dp->codec_dev)
+		mtk_dp->plugged_cb(mtk_dp->codec_dev, connected & has_audio);
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+}
+
 static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 {
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
@@ -2122,6 +2774,7 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 			ret = connector_status_connected;
 	}
 
+	mtk_dp_update_plugged_status(mtk_dp);
 	return ret;
 }
 
@@ -2308,6 +2961,7 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	mtk_dp->state = MTK_DP_STATE_IDLE;
 	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
 
@@ -2345,6 +2999,10 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
 		return;
 	}
 
+	mutex_lock(&mtk_dp->eld_lock);
+	memcpy(mtk_dp->connector_eld, mtk_dp->conn->eld, MAX_ELD_BYTES);
+	mutex_unlock(&mtk_dp->eld_lock);
+
 	mtk_dp->enabled = true;
 }
 
@@ -2491,6 +3149,104 @@ static void mtk_dp_debounce_timer(struct timer_list *t)
 	mtk_dp->need_debounce = true;
 }
 
+/*
+ * HDMI audio codec callbacks
+ */
+static int mtk_dp_audio_hw_params(struct device *dev, void *data,
+				  struct hdmi_codec_daifmt *daifmt,
+				  struct hdmi_codec_params *params)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct mtk_dp_audio_cfg cfg;
+
+	if (!mtk_dp->enabled) {
+		pr_err("%s, DP is not ready!\n", __func__);
+		return -ENODEV;
+	}
+
+	cfg.channels = params->cea.channels;
+	cfg.sample_rate = params->sample_rate;
+	cfg.word_length_bits = 24;
+
+	mtk_dp_audio_setup(mtk_dp, &cfg);
+
+	return 0;
+}
+
+static int mtk_dp_audio_startup(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, false);
+
+	return 0;
+}
+
+static void mtk_dp_audio_shutdown(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, true);
+}
+
+static int mtk_dp_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
+				size_t len)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp->enabled)
+		memcpy(buf, mtk_dp->connector_eld, len);
+	else
+		memset(buf, 0, len);
+
+	return 0;
+}
+
+static int mtk_dp_audio_hook_plugged_cb(struct device *dev, void *data,
+					hdmi_codec_plugged_cb fn,
+					struct device *codec_dev)
+{
+	struct mtk_dp *mtk_dp = data;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	mtk_dp->plugged_cb = fn;
+	mtk_dp->codec_dev = codec_dev;
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+
+	mtk_dp_update_plugged_status(mtk_dp);
+
+	return 0;
+}
+
+static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
+	.hw_params = mtk_dp_audio_hw_params,
+	.audio_startup = mtk_dp_audio_startup,
+	.audio_shutdown = mtk_dp_audio_shutdown,
+	.get_eld = mtk_dp_audio_get_eld,
+	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
+	.no_capture_mute = 1,
+};
+
+static int mtk_dp_register_audio_driver(struct device *dev)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct hdmi_codec_pdata codec_data = {
+		.ops = &mtk_dp_audio_codec_ops,
+		.max_i2s_channels = 8,
+		.i2s = 1,
+		.data = mtk_dp,
+	};
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO, &codec_data,
+					     sizeof(codec_data));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2534,9 +3290,21 @@ static int mtk_dp_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
 
 	mutex_init(&mtk_dp->dp_lock);
+	mutex_init(&mtk_dp->edid_lock);
+	mutex_init(&mtk_dp->eld_lock);
+	mutex_init(&mtk_dp->update_plugged_status_lock);
 
 	platform_set_drvdata(pdev, mtk_dp);
 
+	if (!mtk_dp_is_edp(mtk_dp)) {
+		ret = mtk_dp_register_audio_driver(dev);
+		if (ret) {
+			dev_err(dev, "Failed to register audio driver: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
 							PLATFORM_DEVID_AUTO,
 							&mtk_dp->regs,
@@ -2579,6 +3347,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* [PATCH v10 21/21] drm/mediatek: DP audio support for mt8195
@ 2022-05-23 10:47   ` Guillaume Ranquet
  0 siblings, 0 replies; 450+ messages in thread
From: Guillaume Ranquet @ 2022-05-23 10:47 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

This patch adds audio support to the DP driver for mt8195 with up to 8
channels.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 784 +++++++++++++++++++++++++++++-
 1 file changed, 777 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index c056bc3ca9f6..05da6565c7f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -108,9 +108,41 @@ enum mtk_dp_color_depth {
 	MTK_DP_COLOR_DEPTH_UNKNOWN = 5,
 };
 
+enum mtk_dp_sdp_type {
+	MTK_DP_SDP_NONE = 0x00,
+	MTK_DP_SDP_ACM = 0x01,
+	MTK_DP_SDP_ISRC = 0x02,
+	MTK_DP_SDP_AVI = 0x03,
+	MTK_DP_SDP_AUI = 0x04,
+	MTK_DP_SDP_SPD = 0x05,
+	MTK_DP_SDP_MPEG = 0x06,
+	MTK_DP_SDP_NTSC = 0x07,
+	MTK_DP_SDP_VSP = 0x08,
+	MTK_DP_SDP_VSC = 0x09,
+	MTK_DP_SDP_EXT = 0x0A,
+	MTK_DP_SDP_PPS0 = 0x0B,
+	MTK_DP_SDP_PPS1 = 0x0C,
+	MTK_DP_SDP_PPS2 = 0x0D,
+	MTK_DP_SDP_PPS3 = 0x0E,
+	MTK_DP_SDP_DRM = 0x10,
+	MTK_DP_SDP_MAX_NUM
+};
+
+struct mtk_dp_sdp_packet {
+	enum mtk_dp_sdp_type type;
+	struct dp_sdp sdp;
+};
+
+struct mtk_dp_audio_cfg {
+	int sample_rate;
+	int word_length_bits;
+	int channels;
+};
+
 struct mtk_dp_info {
 	enum mtk_dp_color_depth depth;
 	enum dp_pixelformat format;
+	struct mtk_dp_audio_cfg audio_caps;
 	struct mtk_dp_timings timings;
 };
 
@@ -148,10 +180,22 @@ struct mtk_dp {
 	struct clk *dp_tx_clk;
 
 	bool enabled;
+	bool audio_enable;
 
 	bool has_fec;
 	/* Protects the mtk_dp struct */
 	struct mutex dp_lock;
+	/* Protects the plugged_cb as it's used in both bridge ops and audio */
+	struct mutex update_plugged_status_lock;
+	/* Protects the eld data as it's used in both bridge ops and audio */
+	struct mutex eld_lock;
+	/* Protects edid as it is used in both bridge ops and IRQ handler */
+	struct mutex edid_lock;
+	struct edid *edid;
+
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
+	u8 connector_eld[MAX_ELD_BYTES];
 
 	struct drm_connector *conn;
 	bool need_debounce;
@@ -512,15 +556,363 @@ static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp)
 	return ret;
 }
 
+static int mtk_dp_audio_setup_channels(struct mtk_dp *mtk_dp,
+				       struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	u32 channel_enable_bits;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3324,
+				 AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX,
+			    AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(9), BIT(9));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_PRTY_REGEN_DP_ENC1_P0_MASK,
+			    AU_PRTY_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AU_CH_STS_REGEN_DP_ENC1_P0_MASK,
+			    AU_CH_STS_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304,
+				 AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK,
+			    AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	switch (cfg->channels) {
+	case 2:
+		channel_enable_bits = AUDIO_2CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_2CH_EN_DP_ENC0_P0_MASK;
+		break;
+	case 8:
+	default:
+		channel_enable_bits = AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+				      AUDIO_8CH_EN_DP_ENC0_P0_MASK;
+		break;
+	}
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+				 channel_enable_bits | AU_EN_DP_ENC0_P0_MASK,
+			   AUDIO_2CH_SEL_DP_ENC0_P0_MASK | AUDIO_2CH_EN_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_SEL_DP_ENC0_P0_MASK |
+			   AUDIO_8CH_EN_DP_ENC0_P0_MASK | AU_EN_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	/* audio channel count change reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, 0, BIT(9));
+	if (ret)
+		return ret;
+
+	/* enable audio reset */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(0), BIT(0));
+
+	return ret;
+}
+
+static int mtk_dp_audio_channel_status_set(struct mtk_dp *mtk_dp,
+					   struct mtk_dp_audio_cfg *cfg)
+{
+	int ret;
+	struct snd_aes_iec958 iec = { 0 };
+
+	switch (cfg->sample_rate) {
+	case 32000:
+		iec.status[3] = IEC958_AES3_CON_FS_32000;
+		break;
+	case 44100:
+		iec.status[3] = IEC958_AES3_CON_FS_44100;
+		break;
+	case 48000:
+		iec.status[3] = IEC958_AES3_CON_FS_48000;
+		break;
+	case 88200:
+		iec.status[3] = IEC958_AES3_CON_FS_88200;
+		break;
+	case 96000:
+		iec.status[3] = IEC958_AES3_CON_FS_96000;
+		break;
+	case 192000:
+		iec.status[3] = IEC958_AES3_CON_FS_192000;
+		break;
+	default:
+		iec.status[3] = IEC958_AES3_CON_FS_NOTID;
+		break;
+	}
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16;
+		break;
+	case 20:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_20_16 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	case 24:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_24_20 |
+			IEC958_AES4_CON_MAX_WORDLEN_24;
+		break;
+	default:
+		iec.status[4] = IEC958_AES4_CON_WORDLEN_NOTID;
+	}
+
+	/* IEC 60958 consumer channel status bits */
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_308C,
+				 0,
+			   CH_STATUS_0_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3090,
+				 iec.status[3] << 8,
+			   CH_STATUS_1_DP_ENC0_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3094, iec.status[4],
+				 CH_STATUS_2_DP_ENC0_P0_MASK);
+
+	return ret;
+}
+
+static int mtk_dp_audio_sdp_asp_set_channels(struct mtk_dp *mtk_dp,
+					     int channels)
+{
+	if (channels != 2 && channels != 8)
+		channels = 8;
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_312C,
+			   (channels - 1) << ASP_HB3_DP_ENC0_P0_SHIFT,
+			   ASP_HB2_DP_ENC0_P0_MASK | ASP_HB3_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_audio_set_divider(struct mtk_dp *mtk_dp)
+{
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
+			   AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_MASK);
+}
+
 static bool mtk_dp_plug_state(struct mtk_dp *mtk_dp)
 {
 	return !!(mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3414) &
 		  HPD_DB_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
+static int mtk_dp_sdp_trigger_packet(struct mtk_dp *mtk_dp,
+				     enum mtk_dp_sdp_type type)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, type,
+				 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, SDP_PACKET_W_DP_ENC1_P0,
+				 SDP_PACKET_W_DP_ENC1_P0);
+
+	return ret;
+}
+
+static void mtk_dp_sdp_set_data(struct mtk_dp *mtk_dp, u8 *data_bytes)
+{
+	mtk_dp_bulk_16bit_write(mtk_dp, MTK_DP_ENC1_P0_3200, data_bytes, 0x10);
+}
+
+static void mtk_dp_sdp_set_header(struct mtk_dp *mtk_dp,
+				  enum mtk_dp_sdp_type type,
+				  struct dp_sdp_header *header)
+{
+	u32 db_addr;
+
+	switch (type) {
+	case MTK_DP_SDP_DRM:
+		db_addr = MTK_DP_ENC0_P0_3138;
+		break;
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		db_addr = MTK_DP_ENC0_P0_3130;
+		break;
+	default:
+		db_addr = MTK_DP_ENC0_P0_30D8 + (type - MTK_DP_SDP_ACM) * 8;
+	}
+
+	mtk_dp_bulk_16bit_write(mtk_dp, db_addr, (u8 *)header, 4);
+}
+
+static const u32 mtk_dp_sdp_type_to_reg[MTK_DP_SDP_MAX_NUM] = {
+	/* MTK_DP_SDP_NONE => */ 0x0,
+	/* MTK_DP_SDP_ACM  => */ MTK_DP_ENC0_P0_30B4,
+	/* MTK_DP_SDP_ISRC => */ MTK_DP_ENC0_P0_30B4 + 1,
+	/* MTK_DP_SDP_AVI  => */ MTK_DP_ENC0_P0_30A4 + 1,
+	/* MTK_DP_SDP_AUI  => */ MTK_DP_ENC0_P0_30A8,
+	/* MTK_DP_SDP_SPD  => */ MTK_DP_ENC0_P0_30A8 + 1,
+	/* MTK_DP_SDP_MPEG => */ MTK_DP_ENC0_P0_30AC,
+	/* MTK_DP_SDP_NTSC => */ MTK_DP_ENC0_P0_30AC + 1,
+	/* MTK_DP_SDP_VSP  => */ MTK_DP_ENC0_P0_30B0,
+	/* MTK_DP_SDP_VSC  => */ MTK_DP_ENC0_P0_30B8,
+	/* MTK_DP_SDP_EXT  => */ MTK_DP_ENC0_P0_30B0 + 1,
+	/* MTK_DP_SDP_PPS0 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS1 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS2 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_PPS3 => */ MTK_DP_ENC0_P0_31E8,
+	/* MTK_DP_SDP_DRM  => */ MTK_DP_ENC0_P0_31DC,
+};
+
+static int mtk_dp_disable_sdp(struct mtk_dp *mtk_dp, enum mtk_dp_sdp_type type)
+{
+	if (type == MTK_DP_SDP_NONE)
+		return -EINVAL;
+
+	/* Disable periodic send */
+	return mtk_dp_update_bits(mtk_dp, mtk_dp_sdp_type_to_reg[type] & 0xfffc, 0,
+			   0xFF << ((mtk_dp_sdp_type_to_reg[type] & 3) * 8));
+}
+
+static int mtk_dp_setup_sdp(struct mtk_dp *mtk_dp,
+			    struct mtk_dp_sdp_packet *packet)
+{
+	int ret = -EINVAL;
+
+	mtk_dp_sdp_set_data(mtk_dp, packet->sdp.db);
+	mtk_dp_sdp_set_header(mtk_dp, packet->type, &packet->sdp.sdp_header);
+
+	mtk_dp_disable_sdp(mtk_dp, packet->type);
+
+	switch (packet->type) {
+	case MTK_DP_SDP_NONE:
+		break;
+	case MTK_DP_SDP_ISRC:
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+					 ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+					 SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+					 ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_DRM:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31DC,
+					 5 << HDR0_CFG_DP_ENC0_P0_SHIFT,
+					 HDR0_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
+					 0x1C << ISRC1_HB3_DP_ENC0_P0_SHIFT,
+				   ISRC1_HB3_DP_ENC0_P0_MASK);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280, MTK_DP_SDP_ISRC,
+					 SDP_PACKET_TYPE_DP_ENC1_P0_MASK);
+		if (ret)
+			break;
+
+		if (packet->sdp.sdp_header.HB3 & BIT(2))
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC,
+						 BIT(ISRC_CONT_DP_ENC0_P0_SHIFT),
+					   ISRC_CONT_DP_ENC0_P0_MASK);
+		else
+			ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30BC, 0,
+						 ISRC_CONT_DP_ENC0_P0_MASK);
+
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3280,
+					 SDP_PACKET_W_DP_ENC1_P0,
+				   SDP_PACKET_W_DP_ENC1_P0);
+		if (ret)
+			break;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30B4,
+					 5 << ISRC_CFG_DP_ENC0_P0_SHIFT,
+				   ISRC_CFG_DP_ENC0_P0_MASK);
+		break;
+	case MTK_DP_SDP_ACM:
+	case MTK_DP_SDP_AVI:
+	case MTK_DP_SDP_AUI:
+	case MTK_DP_SDP_SPD:
+	case MTK_DP_SDP_MPEG:
+	case MTK_DP_SDP_NTSC:
+	case MTK_DP_SDP_VSP:
+	case MTK_DP_SDP_VSC:
+	case MTK_DP_SDP_EXT:
+	case MTK_DP_SDP_PPS0:
+	case MTK_DP_SDP_PPS1:
+	case MTK_DP_SDP_PPS2:
+	case MTK_DP_SDP_PPS3:
+		mtk_dp_sdp_trigger_packet(mtk_dp, packet->type);
+		/* Enable periodic sending */
+		ret = mtk_dp_update_bits(mtk_dp,
+					 mtk_dp_sdp_type_to_reg[packet->type] & 0xfffc,
+					 0x05 << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8),
+					 0xff << ((mtk_dp_sdp_type_to_reg[packet->type] & 3) * 8));
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int mtk_dp_sdp_vsc_ext_disable(struct mtk_dp *mtk_dp)
+{
+	int ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A0, 0,
+				 BIT(7) | BIT(8) | BIT(12));
+	if (ret)
+		return ret;
+
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_328C, 0, BIT(7));
+
+	return ret;
+}
+
+static int mtk_dp_aux_irq_clear(struct mtk_dp *mtk_dp)
 {
-	mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
+	return mtk_dp_write(mtk_dp, MTK_DP_AUX_P0_3640,
 		     BIT(AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_DATA_RECV_IRQ_AUX_TX_P0_SHIFT) |
 		     BIT(AUX_RX_ADDR_RECV_IRQ_AUX_TX_P0_SHIFT) |
@@ -1244,20 +1636,71 @@ static int mtk_dp_training_set_scramble(struct mtk_dp *mtk_dp, bool enable)
 			   DP_SCR_EN_DP_TRANS_P0_MASK);
 }
 
-static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
+static int mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 {
+	int ret;
 	u32 val = BIT(VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT);
 
 	if (enable)
 		val |= BIT(VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
-			   VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
-			   VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, val,
+				 VIDEO_MUTE_SEL_DP_ENC0_P0_MASK | VIDEO_MUTE_SW_DP_ENC0_P0_MASK);
+
+	if (ret)
+		return ret;
 
 	if (mtk_dp_is_edp(mtk_dp))
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
 	else
 		mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
+
+	return 0;
+}
+
+static int mtk_dp_audio_mute(struct mtk_dp *mtk_dp, bool mute)
+{
+	int ret;
+
+	if (mute) {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030,
+				   BIT(VBID_AUDIO_MUTE_SW_DP_ENC0_P0_SHIFT) |
+				   BIT(VBID_AUDIO_MUTE_SEL_DP_ENC0_P0_SHIFT),
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088, 0,
+					 AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+	} else {
+		ret = mtk_dp_update_bits(mtk_dp,
+					 MTK_DP_ENC0_P0_3030, 0,
+				   VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0_MASK |
+				   VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088,
+					 BIT(AU_EN_DP_ENC0_P0_SHIFT),
+				   AU_EN_DP_ENC0_P0_MASK);
+		if (ret)
+			return ret;
+
+		/* Send one every two frames */
+		ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_30A4, 0x0F,
+					 AU_TS_CFG_DP_ENC0_P0_MASK);
+	}
+
+	return ret;
 }
 
 static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
@@ -1327,6 +1770,83 @@ static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
 	mtk_dp->info.timings.frame_rate = 60;
 
 	mtk_dp->has_fec = false;
+	mtk_dp->audio_enable = false;
+}
+
+static int mtk_dp_sdp_set_down_cnt_init(struct mtk_dp *mtk_dp,
+					u32 sram_read_start)
+{
+	u32 sdp_down_cnt_init = 0;
+	u32 dc_offset;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	if (mtk_dp->info.timings.pix_rate_khz > 0)
+		sdp_down_cnt_init = sram_read_start *
+				    mtk_dp->train_info.link_rate * 2700 * 8 /
+				    (timings->pix_rate_khz * 4);
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x1A ?
+						  sdp_down_cnt_init :
+						  0x1A; /* 26 */
+		break;
+	case 2:
+		/* case for LowResolution && High Audio Sample Rate */
+		dc_offset = mode.vtotal <= 525 ? 0x04 : 0x00;
+		sdp_down_cnt_init = sdp_down_cnt_init > 0x10 ?
+						  sdp_down_cnt_init :
+						  0x10 + dc_offset; /* 20 or 16 */
+		break;
+	case 4:
+	default:
+		sdp_down_cnt_init =
+			sdp_down_cnt_init > 0x06 ? sdp_down_cnt_init : 0x06; /*6 */
+		break;
+	}
+
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3040,
+			   sdp_down_cnt_init
+				   << SDP_DOWN_CNT_INIT_DP_ENC0_P0_SHIFT,
+			   SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK);
+}
+
+static int mtk_dp_sdp_set_down_cnt_init_in_hblank(struct mtk_dp *mtk_dp)
+{
+	int pix_clk_mhz;
+	u32 dc_offset;
+	u32 spd_down_cnt_init = 0;
+	struct drm_display_mode mode;
+	struct mtk_dp_timings *timings = &mtk_dp->info.timings;
+
+	drm_display_mode_from_videomode(&timings->vm, &mode);
+
+	pix_clk_mhz = mtk_dp->info.format == DP_PIXELFORMAT_YUV420 ?
+				    mtk_dp->info.timings.pix_rate_khz / 2000 :
+				    mtk_dp->info.timings.pix_rate_khz / 1000;
+
+	switch (mtk_dp->train_info.lane_count) {
+	case 1:
+		spd_down_cnt_init = 0x20;
+		break;
+	case 2:
+		dc_offset = (mode.vtotal <= 525) ? 0x14 : 0x00;
+		spd_down_cnt_init = 0x18 + dc_offset;
+		break;
+	case 4:
+	default:
+		dc_offset = (mode.vtotal <= 525) ? 0x08 : 0x00;
+		if (pix_clk_mhz > mtk_dp->train_info.link_rate * 27)
+			spd_down_cnt_init = 0x8;
+		else
+			spd_down_cnt_init = 0x10 + dc_offset;
+		break;
+	}
+	return mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364, spd_down_cnt_init,
+			   SDP_DOWN_CNT_INIT_IN_HBLANK_DP_ENC1_P0_MASK);
 }
 
 static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
@@ -1343,6 +1863,8 @@ static void mtk_dp_setup_tu(struct mtk_dp *mtk_dp)
 	}
 
 	mtk_dp_setup_encoder(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init_in_hblank(mtk_dp);
+	mtk_dp_sdp_set_down_cnt_init(mtk_dp, sram_read_start);
 }
 
 static void mtk_dp_calculate_pixrate(struct mtk_dp *mtk_dp)
@@ -1420,6 +1942,17 @@ static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
 	return 0;
 }
 
+static void mtk_dp_sdp_stop_sending(struct mtk_dp *mtk_dp)
+{
+	u8 packet_type;
+
+	for (packet_type = MTK_DP_SDP_ACM; packet_type < MTK_DP_SDP_MAX_NUM;
+	     packet_type++)
+		mtk_dp_disable_sdp(mtk_dp, packet_type);
+
+	mtk_dp_sdp_vsc_ext_disable(mtk_dp);
+}
+
 static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
 					  u8 dpcd_adjust_req[2])
 {
@@ -1725,6 +2258,52 @@ static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
 	return true;
 }
 
+static int mtk_dp_edid_parse_audio_capabilities(struct mtk_dp *mtk_dp,
+						struct mtk_dp_audio_cfg *cfg)
+{
+	struct cea_sad *sads;
+	int sad_count;
+	int i;
+	int ret = 0;
+
+	mutex_lock(&mtk_dp->edid_lock);
+	if (!mtk_dp->edid) {
+		mutex_unlock(&mtk_dp->edid_lock);
+		dev_err(mtk_dp->dev, "EDID not found!\n");
+		return -EINVAL;
+	}
+
+	sad_count = drm_edid_to_sad(mtk_dp->edid, &sads);
+	mutex_unlock(&mtk_dp->edid_lock);
+	if (sad_count <= 0) {
+		drm_info(mtk_dp->drm_dev, "The SADs is NULL\n");
+		return 0;
+	}
+
+	for (i = 0; i < sad_count; i++) {
+		int sample_rate;
+		int word_length;
+		/* Only PCM supported at the moment */
+		if (sads[i].format != HDMI_AUDIO_CODING_TYPE_PCM)
+			continue;
+
+		sample_rate = drm_cea_sad_get_sample_rate(&sads[i]);
+		word_length =
+			drm_cea_sad_get_uncompressed_word_length(&sads[i]);
+		if (sample_rate <= 0 || word_length <= 0)
+			continue;
+
+		cfg->channels = sads[i].channels;
+		cfg->word_length_bits = word_length;
+		cfg->sample_rate = sample_rate;
+		ret = 1;
+		break;
+	}
+	kfree(sads);
+
+	return ret;
+}
+
 static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
 {
 	phy_reset(mtk_dp->phy);
@@ -1830,6 +2409,48 @@ static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
 	}
 }
 
+static void mtk_dp_audio_sdp_setup(struct mtk_dp *mtk_dp,
+				   struct mtk_dp_audio_cfg *cfg)
+{
+	struct mtk_dp_sdp_packet packet;
+	struct hdmi_audio_infoframe frame;
+
+	hdmi_audio_infoframe_init(&frame);
+	frame.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;
+	frame.channels = cfg->channels;
+	frame.sample_frequency = cfg->sample_rate;
+
+	switch (cfg->word_length_bits) {
+	case 16:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		break;
+	case 20:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
+		break;
+	case 24:
+	default:
+		frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
+		break;
+	}
+
+	packet.type = MTK_DP_SDP_AUI;
+	hdmi_audio_infoframe_pack_for_dp(&frame, &packet.sdp,
+					 MTK_DP_DP_VERSION_11);
+
+	mtk_dp_audio_sdp_asp_set_channels(mtk_dp, cfg->channels);
+	mtk_dp_setup_sdp(mtk_dp, &packet);
+}
+
+static void mtk_dp_audio_setup(struct mtk_dp *mtk_dp,
+			       struct mtk_dp_audio_cfg *cfg)
+{
+	mtk_dp_audio_sdp_setup(mtk_dp, cfg);
+	mtk_dp_audio_channel_status_set(mtk_dp, cfg);
+
+	mtk_dp_audio_setup_channels(mtk_dp, cfg);
+	mtk_dp_audio_set_divider(mtk_dp);
+}
+
 static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
 {
 	mtk_dp_mn_overwrite_disable(mtk_dp);
@@ -1845,6 +2466,7 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 	switch (mtk_dp->state) {
 	case MTK_DP_STATE_INITIAL:
 		mtk_dp_video_mute(mtk_dp, true);
+		mtk_dp_audio_mute(mtk_dp, true);
 		mtk_dp->state = MTK_DP_STATE_IDLE;
 		break;
 
@@ -1857,12 +2479,19 @@ static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
 		mtk_dp_video_config(mtk_dp);
 		mtk_dp_video_enable(mtk_dp, true);
 
+		if (mtk_dp->audio_enable) {
+			mtk_dp_audio_setup(mtk_dp, &mtk_dp->info.audio_caps);
+			mtk_dp_audio_mute(mtk_dp, false);
+		}
+
 		mtk_dp->state = MTK_DP_STATE_NORMAL;
 		break;
 
 	case MTK_DP_STATE_NORMAL:
 		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 			mtk_dp->state = MTK_DP_STATE_IDLE;
 		}
 		break;
@@ -1901,7 +2530,15 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			}
 			break;
 
-		case MTK_DP_TRAIN_STATE_CHECKEDID:
+		case MTK_DP_TRAIN_STATE_CHECKEDID: {
+			int caps_found = mtk_dp_edid_parse_audio_capabilities(mtk_dp,
+				&mtk_dp->info.audio_caps);
+			mtk_dp->audio_enable = caps_found > 0;
+			if (!mtk_dp->audio_enable)
+				memset(&mtk_dp->info.audio_caps, 0,
+				       sizeof(mtk_dp->info.audio_caps));
+		}
+
 			mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
 			break;
 
@@ -1914,6 +2551,7 @@ static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
 			ret = mtk_dp_train_start(mtk_dp);
 			if (ret == 0) {
 				mtk_dp_video_mute(mtk_dp, true);
+				mtk_dp_audio_mute(mtk_dp, true);
 				mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;
 				mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
 			} else if (ret != -EAGAIN) {
@@ -1988,11 +2626,13 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 		if (!mtk_dp->train_info.cable_plugged_in ||
 		    !mtk_dp_plug_state(mtk_dp)) {
 			mtk_dp_video_mute(mtk_dp, true);
+			mtk_dp_audio_mute(mtk_dp, true);
 
 			mtk_dp_initialize_priv_data(mtk_dp);
 			mtk_dp_set_idle_pattern(mtk_dp, true);
 			if (mtk_dp->has_fec)
 				mtk_dp_fec_enable(mtk_dp, false);
+			mtk_dp_sdp_stop_sending(mtk_dp);
 
 			mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
 					   DP_PWR_STATE_BANDGAP_TPLL,
@@ -2107,6 +2747,18 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	return ret;
 }
 
+static void mtk_dp_update_plugged_status(struct mtk_dp *mtk_dp)
+{
+	bool connected, has_audio;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	connected = mtk_dp_plug_state(mtk_dp);
+	has_audio = drm_detect_monitor_audio(mtk_dp->edid);
+	if (mtk_dp->plugged_cb && mtk_dp->codec_dev)
+		mtk_dp->plugged_cb(mtk_dp->codec_dev, connected & has_audio);
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+}
+
 static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 {
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
@@ -2122,6 +2774,7 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 			ret = connector_status_connected;
 	}
 
+	mtk_dp_update_plugged_status(mtk_dp);
 	return ret;
 }
 
@@ -2308,6 +2961,7 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	mtk_dp->state = MTK_DP_STATE_IDLE;
 	mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
 
@@ -2345,6 +2999,10 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
 		return;
 	}
 
+	mutex_lock(&mtk_dp->eld_lock);
+	memcpy(mtk_dp->connector_eld, mtk_dp->conn->eld, MAX_ELD_BYTES);
+	mutex_unlock(&mtk_dp->eld_lock);
+
 	mtk_dp->enabled = true;
 }
 
@@ -2491,6 +3149,104 @@ static void mtk_dp_debounce_timer(struct timer_list *t)
 	mtk_dp->need_debounce = true;
 }
 
+/*
+ * HDMI audio codec callbacks
+ */
+static int mtk_dp_audio_hw_params(struct device *dev, void *data,
+				  struct hdmi_codec_daifmt *daifmt,
+				  struct hdmi_codec_params *params)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct mtk_dp_audio_cfg cfg;
+
+	if (!mtk_dp->enabled) {
+		pr_err("%s, DP is not ready!\n", __func__);
+		return -ENODEV;
+	}
+
+	cfg.channels = params->cea.channels;
+	cfg.sample_rate = params->sample_rate;
+	cfg.word_length_bits = 24;
+
+	mtk_dp_audio_setup(mtk_dp, &cfg);
+
+	return 0;
+}
+
+static int mtk_dp_audio_startup(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, false);
+
+	return 0;
+}
+
+static void mtk_dp_audio_shutdown(struct device *dev, void *data)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	mtk_dp_audio_mute(mtk_dp, true);
+}
+
+static int mtk_dp_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
+				size_t len)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+
+	if (mtk_dp->enabled)
+		memcpy(buf, mtk_dp->connector_eld, len);
+	else
+		memset(buf, 0, len);
+
+	return 0;
+}
+
+static int mtk_dp_audio_hook_plugged_cb(struct device *dev, void *data,
+					hdmi_codec_plugged_cb fn,
+					struct device *codec_dev)
+{
+	struct mtk_dp *mtk_dp = data;
+
+	mutex_lock(&mtk_dp->update_plugged_status_lock);
+	mtk_dp->plugged_cb = fn;
+	mtk_dp->codec_dev = codec_dev;
+	mutex_unlock(&mtk_dp->update_plugged_status_lock);
+
+	mtk_dp_update_plugged_status(mtk_dp);
+
+	return 0;
+}
+
+static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
+	.hw_params = mtk_dp_audio_hw_params,
+	.audio_startup = mtk_dp_audio_startup,
+	.audio_shutdown = mtk_dp_audio_shutdown,
+	.get_eld = mtk_dp_audio_get_eld,
+	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
+	.no_capture_mute = 1,
+};
+
+static int mtk_dp_register_audio_driver(struct device *dev)
+{
+	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	struct hdmi_codec_pdata codec_data = {
+		.ops = &mtk_dp_audio_codec_ops,
+		.max_i2s_channels = 8,
+		.i2s = 1,
+		.data = mtk_dp,
+	};
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO, &codec_data,
+					     sizeof(codec_data));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2534,9 +3290,21 @@ static int mtk_dp_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -EPROBE_DEFER, "failed to request mediatek dptx irq\n");
 
 	mutex_init(&mtk_dp->dp_lock);
+	mutex_init(&mtk_dp->edid_lock);
+	mutex_init(&mtk_dp->eld_lock);
+	mutex_init(&mtk_dp->update_plugged_status_lock);
 
 	platform_set_drvdata(pdev, mtk_dp);
 
+	if (!mtk_dp_is_edp(mtk_dp)) {
+		ret = mtk_dp_register_audio_driver(dev);
+		if (ret) {
+			dev_err(dev, "Failed to register audio driver: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
 							PLATFORM_DEVID_AUTO,
 							&mtk_dp->regs,
@@ -2579,6 +3347,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	platform_device_unregister(mtk_dp->phy_dev);
 	mtk_dp_video_mute(mtk_dp, true);
+	mtk_dp_audio_mute(mtk_dp, true);
 	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 10:57     ` Matthias Brugger
  -1 siblings, 0 replies; 450+ messages in thread
From: Matthias Brugger @ 2022-05-23 10:57 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

We need a commit message here.

> ---
>  include/drm/drm_edid.h | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>  
>  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> << 8))
>  
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.
> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>  struct cea_sad {
>         u8 format;
> -       u8 channels; /* max number of channels - 1 */
> +       u8 channels;
>         u8 freq;
> -       u8 byte2; /* meaning depends on format */
> +       u8 byte2;
>  };
>  
>  struct drm_encoder;


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-23 10:57     ` Matthias Brugger
  0 siblings, 0 replies; 450+ messages in thread
From: Matthias Brugger @ 2022-05-23 10:57 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

We need a commit message here.

> ---
>  include/drm/drm_edid.h | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>  
>  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> << 8))
>  
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.
> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>  struct cea_sad {
>         u8 format;
> -       u8 channels; /* max number of channels - 1 */
> +       u8 channels;
>         u8 freq;
> -       u8 byte2; /* meaning depends on format */
> +       u8 byte2;
>  };
>  
>  struct drm_encoder;


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-23 10:57     ` Matthias Brugger
  0 siblings, 0 replies; 450+ messages in thread
From: Matthias Brugger @ 2022-05-23 10:57 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

We need a commit message here.

> ---
>  include/drm/drm_edid.h | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>  
>  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> << 8))
>  
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.
> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>  struct cea_sad {
>         u8 format;
> -       u8 channels; /* max number of channels - 1 */
> +       u8 channels;
>         u8 freq;
> -       u8 byte2; /* meaning depends on format */
> +       u8 byte2;
>  };
>  
>  struct drm_encoder;


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-23 10:57     ` Matthias Brugger
  0 siblings, 0 replies; 450+ messages in thread
From: Matthias Brugger @ 2022-05-23 10:57 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

We need a commit message here.

> ---
>  include/drm/drm_edid.h | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>  
>  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> << 8))
>  
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.
> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>  struct cea_sad {
>         u8 format;
> -       u8 channels; /* max number of channels - 1 */
> +       u8 channels;
>         u8 freq;
> -       u8 byte2; /* meaning depends on format */
> +       u8 byte2;
>  };
>  
>  struct drm_encoder;


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-23 10:57     ` Matthias Brugger
  0 siblings, 0 replies; 450+ messages in thread
From: Matthias Brugger @ 2022-05-23 10:57 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

We need a commit message here.

> ---
>  include/drm/drm_edid.h | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>  
>  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> << 8))
>  
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.
> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>  struct cea_sad {
>         u8 format;
> -       u8 channels; /* max number of channels - 1 */
> +       u8 channels;
>         u8 freq;
> -       u8 byte2; /* meaning depends on format */
> +       u8 byte2;
>  };
>  
>  struct drm_encoder;


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-23 12:33     ` Rob Herring
  -1 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-05-23 12:33 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Philipp Zabel, Jitao shi, linux-mediatek, CK Hu,
	Maarten Lankhorst, linux-kernel, dri-devel, linux-fbdev,
	Matthias Brugger, devicetree, Rob Herring, Chunfeng Yun,
	Krzysztof Kozlowski, Vinod Koul, Chun-Kuang Hu, Helge Deller,
	Kishon Vijay Abraham I, linux-phy, Daniel Vetter,
	Thomas Zimmermann, David Airlie, Markus Schneider-Pargmann,
	Maxime Ripard, linux-arm-kernel

On Mon, 23 May 2022 12:47:34 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/


dpi@14014000: Additional properties are not allowed ('ports' was unexpected)
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clocks: [[59, 26], [59, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb

dpi@14014000: clocks: [[61, 26], [61, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: compatible: ['mediatek,mt7623-dpi', 'mediatek,mt2701-dpi'] is too long
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: 'port' is a required property
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@1401d000: Additional properties are not allowed ('power-domains' was unexpected)
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[57, 40], [57, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[68, 40], [68, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek, dpi: Add DPINTF compatible
@ 2022-05-23 12:33     ` Rob Herring
  0 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-05-23 12:33 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: linux-fbdev, Chun-Kuang Hu, David Airlie, dri-devel,
	Krzysztof Kozlowski, linux-phy, Helge Deller,
	Kishon Vijay Abraham I, Chunfeng Yun, devicetree, Jitao shi,
	Markus Schneider-Pargmann, Rob Herring, linux-mediatek,
	Matthias Brugger, linux-arm-kernel, linux-kernel, Vinod Koul,
	Thomas Zimmermann

On Mon, 23 May 2022 12:47:34 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/


dpi@14014000: Additional properties are not allowed ('ports' was unexpected)
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clocks: [[59, 26], [59, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb

dpi@14014000: clocks: [[61, 26], [61, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: compatible: ['mediatek,mt7623-dpi', 'mediatek,mt2701-dpi'] is too long
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: 'port' is a required property
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@1401d000: Additional properties are not allowed ('power-domains' was unexpected)
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[57, 40], [57, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[68, 40], [68, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek, dpi: Add DPINTF compatible
@ 2022-05-23 12:33     ` Rob Herring
  0 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-05-23 12:33 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Philipp Zabel, Jitao shi, linux-mediatek, CK Hu,
	Maarten Lankhorst, linux-kernel, dri-devel, linux-fbdev,
	Matthias Brugger, devicetree, Rob Herring, Chunfeng Yun,
	Krzysztof Kozlowski, Vinod Koul, Chun-Kuang Hu, Helge Deller,
	Kishon Vijay Abraham I, linux-phy, Daniel Vetter,
	Thomas Zimmermann, David Airlie, Markus Schneider-Pargmann,
	Maxime Ripard, linux-arm-kernel

On Mon, 23 May 2022 12:47:34 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/


dpi@14014000: Additional properties are not allowed ('ports' was unexpected)
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clocks: [[59, 26], [59, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb

dpi@14014000: clocks: [[61, 26], [61, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: compatible: ['mediatek,mt7623-dpi', 'mediatek,mt2701-dpi'] is too long
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: 'port' is a required property
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@1401d000: Additional properties are not allowed ('power-domains' was unexpected)
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[57, 40], [57, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[68, 40], [68, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek, dpi: Add DPINTF compatible
@ 2022-05-23 12:33     ` Rob Herring
  0 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-05-23 12:33 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Philipp Zabel, Jitao shi, linux-mediatek, CK Hu,
	Maarten Lankhorst, linux-kernel, dri-devel, linux-fbdev,
	Matthias Brugger, devicetree, Rob Herring, Chunfeng Yun,
	Krzysztof Kozlowski, Vinod Koul, Chun-Kuang Hu, Helge Deller,
	Kishon Vijay Abraham I, linux-phy, Daniel Vetter,
	Thomas Zimmermann, David Airlie, Markus Schneider-Pargmann,
	Maxime Ripard, linux-arm-kernel

On Mon, 23 May 2022 12:47:34 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/


dpi@14014000: Additional properties are not allowed ('ports' was unexpected)
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clocks: [[59, 26], [59, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb

dpi@14014000: clocks: [[61, 26], [61, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: compatible: ['mediatek,mt7623-dpi', 'mediatek,mt2701-dpi'] is too long
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: 'port' is a required property
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@1401d000: Additional properties are not allowed ('power-domains' was unexpected)
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[57, 40], [57, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[68, 40], [68, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek, dpi: Add DPINTF compatible
@ 2022-05-23 12:33     ` Rob Herring
  0 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-05-23 12:33 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Philipp Zabel, Jitao shi, linux-mediatek, CK Hu,
	Maarten Lankhorst, linux-kernel, dri-devel, linux-fbdev,
	Matthias Brugger, devicetree, Rob Herring, Chunfeng Yun,
	Krzysztof Kozlowski, Vinod Koul, Chun-Kuang Hu, Helge Deller,
	Kishon Vijay Abraham I, linux-phy, Daniel Vetter,
	Thomas Zimmermann, David Airlie, Markus Schneider-Pargmann,
	Maxime Ripard, linux-arm-kernel

On Mon, 23 May 2022 12:47:34 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/


dpi@14014000: Additional properties are not allowed ('ports' was unexpected)
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: clocks: [[59, 26], [59, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb

dpi@14014000: clocks: [[61, 26], [61, 27], [3, 6]] is too short
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: compatible: ['mediatek,mt7623-dpi', 'mediatek,mt2701-dpi'] is too long
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@14014000: 'port' is a required property
	arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb
	arch/arm/boot/dts/mt7623n-rfb-emmc.dtb

dpi@1401d000: Additional properties are not allowed ('power-domains' was unexpected)
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clock-names: ['pixel', 'engine', 'pll'] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[57, 40], [57, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-evb.dtb

dpi@1401d000: clocks: [[68, 40], [68, 41], [8, 8]] is too short
	arch/arm64/boot/dts/mediatek/mt8173-elm.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb
	arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-24  3:29     ` Chunfeng Yun
  -1 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:29 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++---
> --
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> index dd2896a40ff0..6d9f6c11806e 100644
> ---
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> @@ -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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>        - description: Pixel Clock
>        - description: Engine Clock
>        - description: DPI PLL
> +      - description: Optional CK CG Clock
>  
>    clock-names:
>      items:
>        - const: pixel
>        - const: engine
>        - const: pll
> +      - const: ck_cg
'ck_cg' seems not a exact clock names, could you pleas check it again
with DE.

>  
>    pinctrl-0: true
>    pinctrl-1: true
> @@ -54,7 +57,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


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-24  3:29     ` Chunfeng Yun
  0 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:29 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++---
> --
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> index dd2896a40ff0..6d9f6c11806e 100644
> ---
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> @@ -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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>        - description: Pixel Clock
>        - description: Engine Clock
>        - description: DPI PLL
> +      - description: Optional CK CG Clock
>  
>    clock-names:
>      items:
>        - const: pixel
>        - const: engine
>        - const: pll
> +      - const: ck_cg
'ck_cg' seems not a exact clock names, could you pleas check it again
with DE.

>  
>    pinctrl-0: true
>    pinctrl-1: true
> @@ -54,7 +57,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


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-24  3:29     ` Chunfeng Yun
  0 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:29 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++---
> --
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> index dd2896a40ff0..6d9f6c11806e 100644
> ---
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> @@ -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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>        - description: Pixel Clock
>        - description: Engine Clock
>        - description: DPI PLL
> +      - description: Optional CK CG Clock
>  
>    clock-names:
>      items:
>        - const: pixel
>        - const: engine
>        - const: pll
> +      - const: ck_cg
'ck_cg' seems not a exact clock names, could you pleas check it again
with DE.

>  
>    pinctrl-0: true
>    pinctrl-1: true
> @@ -54,7 +57,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
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-24  3:29     ` Chunfeng Yun
  0 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:29 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++---
> --
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> index dd2896a40ff0..6d9f6c11806e 100644
> ---
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> @@ -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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>        - description: Pixel Clock
>        - description: Engine Clock
>        - description: DPI PLL
> +      - description: Optional CK CG Clock
>  
>    clock-names:
>      items:
>        - const: pixel
>        - const: engine
>        - const: pll
> +      - const: ck_cg
'ck_cg' seems not a exact clock names, could you pleas check it again
with DE.

>  
>    pinctrl-0: true
>    pinctrl-1: true
> @@ -54,7 +57,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
-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-24  3:29     ` Chunfeng Yun
  0 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:29 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++---
> --
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> index dd2896a40ff0..6d9f6c11806e 100644
> ---
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yam
> l
> @@ -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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>        - description: Pixel Clock
>        - description: Engine Clock
>        - description: DPI PLL
> +      - description: Optional CK CG Clock
>  
>    clock-names:
>      items:
>        - const: pixel
>        - const: engine
>        - const: pll
> +      - const: ck_cg
'ck_cg' seems not a exact clock names, could you pleas check it again
with DE.

>  
>    pinctrl-0: true
>    pinctrl-1: true
> @@ -54,7 +57,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
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-24  3:35     ` Chunfeng Yun
  -1 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:35 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99
> +++++++++++++++++++
>  1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +
> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
'edp_tx: ' can be removed

> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
reg = <0x1c500000 0x8000>;
#address-cells, #size-cells are both 1 by default

> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-24  3:35     ` Chunfeng Yun
  0 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:35 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99
> +++++++++++++++++++
>  1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +
> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
'edp_tx: ' can be removed

> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
reg = <0x1c500000 0x8000>;
#address-cells, #size-cells are both 1 by default

> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-24  3:35     ` Chunfeng Yun
  0 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:35 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99
> +++++++++++++++++++
>  1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +
> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
'edp_tx: ' can be removed

> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
reg = <0x1c500000 0x8000>;
#address-cells, #size-cells are both 1 by default

> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };
-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-24  3:35     ` Chunfeng Yun
  0 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:35 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99
> +++++++++++++++++++
>  1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +
> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
'edp_tx: ' can be removed

> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
reg = <0x1c500000 0x8000>;
#address-cells, #size-cells are both 1 by default

> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-24  3:35     ` Chunfeng Yun
  0 siblings, 0 replies; 450+ messages in thread
From: Chunfeng Yun @ 2022-05-24  3:35 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99
> +++++++++++++++++++
>  1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +
> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
'edp_tx: ' can be removed

> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
reg = <0x1c500000 0x8000>;
#address-cells, #size-cells are both 1 by default

> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25  5:47     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-25  5:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)

I don't have a DP spec. I find one in [1] but I'm not sure it's real
spec or not. If it's real, in section 3.1.3.2, it describe:

3.1.3.2 Hot Plug/Unplug Detection
One signal (HPD) is used by a device (an Upstream device) to detect
that a Downstream port on the device has been connected to another
device (the Downstream device). Implementation of HPD is optional for
an embedded link configuration. At least a “trickle power” must be
present both in the Upstream and Downstream devices for a Hot Plug
event to be detected. 

I focus on the statement "Implementation of HPD is optional for an
embedded link configuration". I'm not sure what does 'optional' mean.
Does it mean eDP panel without HPD signal is possible? If so, I think
driver should support eDP panel without HPD signal. Maybe I
misunderstanding this spec. Please explain for me.

Regards,
CK


[1] https://glenwing.github.io/docs/DP-1.2.pdf

> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-25  5:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-25  5:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)

I don't have a DP spec. I find one in [1] but I'm not sure it's real
spec or not. If it's real, in section 3.1.3.2, it describe:

3.1.3.2 Hot Plug/Unplug Detection
One signal (HPD) is used by a device (an Upstream device) to detect
that a Downstream port on the device has been connected to another
device (the Downstream device). Implementation of HPD is optional for
an embedded link configuration. At least a “trickle power” must be
present both in the Upstream and Downstream devices for a Hot Plug
event to be detected. 

I focus on the statement "Implementation of HPD is optional for an
embedded link configuration". I'm not sure what does 'optional' mean.
Does it mean eDP panel without HPD signal is possible? If so, I think
driver should support eDP panel without HPD signal. Maybe I
misunderstanding this spec. Please explain for me.

Regards,
CK


[1] https://glenwing.github.io/docs/DP-1.2.pdf

> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-25  5:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-25  5:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)

I don't have a DP spec. I find one in [1] but I'm not sure it's real
spec or not. If it's real, in section 3.1.3.2, it describe:

3.1.3.2 Hot Plug/Unplug Detection
One signal (HPD) is used by a device (an Upstream device) to detect
that a Downstream port on the device has been connected to another
device (the Downstream device). Implementation of HPD is optional for
an embedded link configuration. At least a “trickle power” must be
present both in the Upstream and Downstream devices for a Hot Plug
event to be detected. 

I focus on the statement "Implementation of HPD is optional for an
embedded link configuration". I'm not sure what does 'optional' mean.
Does it mean eDP panel without HPD signal is possible? If so, I think
driver should support eDP panel without HPD signal. Maybe I
misunderstanding this spec. Please explain for me.

Regards,
CK


[1] https://glenwing.github.io/docs/DP-1.2.pdf

> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-25  5:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-25  5:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)

I don't have a DP spec. I find one in [1] but I'm not sure it's real
spec or not. If it's real, in section 3.1.3.2, it describe:

3.1.3.2 Hot Plug/Unplug Detection
One signal (HPD) is used by a device (an Upstream device) to detect
that a Downstream port on the device has been connected to another
device (the Downstream device). Implementation of HPD is optional for
an embedded link configuration. At least a “trickle power” must be
present both in the Upstream and Downstream devices for a Hot Plug
event to be detected. 

I focus on the statement "Implementation of HPD is optional for an
embedded link configuration". I'm not sure what does 'optional' mean.
Does it mean eDP panel without HPD signal is possible? If so, I think
driver should support eDP panel without HPD signal. Maybe I
misunderstanding this spec. Please explain for me.

Regards,
CK


[1] https://glenwing.github.io/docs/DP-1.2.pdf

> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-25  5:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-25  5:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)

I don't have a DP spec. I find one in [1] but I'm not sure it's real
spec or not. If it's real, in section 3.1.3.2, it describe:

3.1.3.2 Hot Plug/Unplug Detection
One signal (HPD) is used by a device (an Upstream device) to detect
that a Downstream port on the device has been connected to another
device (the Downstream device). Implementation of HPD is optional for
an embedded link configuration. At least a “trickle power” must be
present both in the Upstream and Downstream devices for a Hot Plug
event to be detected. 

I focus on the statement "Implementation of HPD is optional for an
embedded link configuration". I'm not sure what does 'optional' mean.
Does it mean eDP panel without HPD signal is possible? If so, I think
driver should support eDP panel without HPD signal. Maybe I
misunderstanding this spec. Please explain for me.

Regards,
CK


[1] https://glenwing.github.io/docs/DP-1.2.pdf

> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25 11:55     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 11:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>   1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>   
>   maintainers:
>     - CK Hu <ck.hu@mediatek.com>
>     - Jitao shi <jitao.shi@mediatek.com>
>   
>   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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>         - description: Pixel Clock
>         - description: Engine Clock
>         - description: DPI PLL
> +      - description: Optional CK CG Clock
>   
>     clock-names:
>       items:
>         - const: pixel
>         - const: engine
>         - const: pll
> +      - const: ck_cg

This is my understanding on how the DisplayPort Interface clocks work on 8195:

The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
"pll" is for TVD PLL divider selection
"pixel" is the gate for the pixel clock to the connected display.

"ck_cg" is useless, as that's the parent of "pixel" (and will always be)... for
example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its parent, hence
enabling the first will enable the latter.

That said... you can most probably avoid adding the ck_cg clock, as if you try
to turn that off while it's in use by its children, you'll be only decrementing
a refcount, but no "real action" will ever take place.


Regards,
Angelo

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-25 11:55     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 11:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>   1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>   
>   maintainers:
>     - CK Hu <ck.hu@mediatek.com>
>     - Jitao shi <jitao.shi@mediatek.com>
>   
>   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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>         - description: Pixel Clock
>         - description: Engine Clock
>         - description: DPI PLL
> +      - description: Optional CK CG Clock
>   
>     clock-names:
>       items:
>         - const: pixel
>         - const: engine
>         - const: pll
> +      - const: ck_cg

This is my understanding on how the DisplayPort Interface clocks work on 8195:

The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
"pll" is for TVD PLL divider selection
"pixel" is the gate for the pixel clock to the connected display.

"ck_cg" is useless, as that's the parent of "pixel" (and will always be)... for
example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its parent, hence
enabling the first will enable the latter.

That said... you can most probably avoid adding the ck_cg clock, as if you try
to turn that off while it's in use by its children, you'll be only decrementing
a refcount, but no "real action" will ever take place.


Regards,
Angelo

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-25 11:55     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 11:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>   1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>   
>   maintainers:
>     - CK Hu <ck.hu@mediatek.com>
>     - Jitao shi <jitao.shi@mediatek.com>
>   
>   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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>         - description: Pixel Clock
>         - description: Engine Clock
>         - description: DPI PLL
> +      - description: Optional CK CG Clock
>   
>     clock-names:
>       items:
>         - const: pixel
>         - const: engine
>         - const: pll
> +      - const: ck_cg

This is my understanding on how the DisplayPort Interface clocks work on 8195:

The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
"pll" is for TVD PLL divider selection
"pixel" is the gate for the pixel clock to the connected display.

"ck_cg" is useless, as that's the parent of "pixel" (and will always be)... for
example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its parent, hence
enabling the first will enable the latter.

That said... you can most probably avoid adding the ck_cg clock, as if you try
to turn that off while it's in use by its children, you'll be only decrementing
a refcount, but no "real action" will ever take place.


Regards,
Angelo

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-25 11:55     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 11:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>   1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>   
>   maintainers:
>     - CK Hu <ck.hu@mediatek.com>
>     - Jitao shi <jitao.shi@mediatek.com>
>   
>   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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>         - description: Pixel Clock
>         - description: Engine Clock
>         - description: DPI PLL
> +      - description: Optional CK CG Clock
>   
>     clock-names:
>       items:
>         - const: pixel
>         - const: engine
>         - const: pll
> +      - const: ck_cg

This is my understanding on how the DisplayPort Interface clocks work on 8195:

The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
"pll" is for TVD PLL divider selection
"pixel" is the gate for the pixel clock to the connected display.

"ck_cg" is useless, as that's the parent of "pixel" (and will always be)... for
example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its parent, hence
enabling the first will enable the latter.

That said... you can most probably avoid adding the ck_cg clock, as if you try
to turn that off while it's in use by its children, you'll be only decrementing
a refcount, but no "real action" will ever take place.


Regards,
Angelo

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-25 11:55     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 11:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>   1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>   
>   maintainers:
>     - CK Hu <ck.hu@mediatek.com>
>     - Jitao shi <jitao.shi@mediatek.com>
>   
>   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 DPINTF 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
> @@ -35,12 +36,14 @@ properties:
>         - description: Pixel Clock
>         - description: Engine Clock
>         - description: DPI PLL
> +      - description: Optional CK CG Clock
>   
>     clock-names:
>       items:
>         - const: pixel
>         - const: engine
>         - const: pll
> +      - const: ck_cg

This is my understanding on how the DisplayPort Interface clocks work on 8195:

The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
"pll" is for TVD PLL divider selection
"pixel" is the gate for the pixel clock to the connected display.

"ck_cg" is useless, as that's the parent of "pixel" (and will always be)... for
example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its parent, hence
enabling the first will enable the latter.

That said... you can most probably avoid adding the ck_cg clock, as if you try
to turn that off while it's in use by its children, you'll be only decrementing
a refcount, but no "real action" will ever take place.


Regards,
Angelo

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25 12:01     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:01 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   include/drm/drm_edid.h | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>   
>   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
>   
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.

Perhaps....

* struct cea_sad - CEA Short Audio Descriptor

...but that's relative to personal liking and nothing else, it's also fine as
it is, if you like it more as it is. The ball is yours :-P

Regardless of any choice about changing the description or not:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Cheers,
Angelo

> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>   struct cea_sad {
>   	u8 format;
> -	u8 channels; /* max number of channels - 1 */
> +	u8 channels;
>   	u8 freq;
> -	u8 byte2; /* meaning depends on format */
> +	u8 byte2;
>   };
>   
>   struct drm_encoder;


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-25 12:01     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:01 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   include/drm/drm_edid.h | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>   
>   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
>   
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.

Perhaps....

* struct cea_sad - CEA Short Audio Descriptor

...but that's relative to personal liking and nothing else, it's also fine as
it is, if you like it more as it is. The ball is yours :-P

Regardless of any choice about changing the description or not:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Cheers,
Angelo

> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>   struct cea_sad {
>   	u8 format;
> -	u8 channels; /* max number of channels - 1 */
> +	u8 channels;
>   	u8 freq;
> -	u8 byte2; /* meaning depends on format */
> +	u8 byte2;
>   };
>   
>   struct drm_encoder;


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-25 12:01     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:01 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   include/drm/drm_edid.h | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>   
>   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
>   
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.

Perhaps....

* struct cea_sad - CEA Short Audio Descriptor

...but that's relative to personal liking and nothing else, it's also fine as
it is, if you like it more as it is. The ball is yours :-P

Regardless of any choice about changing the description or not:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Cheers,
Angelo

> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>   struct cea_sad {
>   	u8 format;
> -	u8 channels; /* max number of channels - 1 */
> +	u8 channels;
>   	u8 freq;
> -	u8 byte2; /* meaning depends on format */
> +	u8 byte2;
>   };
>   
>   struct drm_encoder;


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-25 12:01     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:01 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   include/drm/drm_edid.h | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>   
>   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
>   
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.

Perhaps....

* struct cea_sad - CEA Short Audio Descriptor

...but that's relative to personal liking and nothing else, it's also fine as
it is, if you like it more as it is. The ball is yours :-P

Regardless of any choice about changing the description or not:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Cheers,
Angelo

> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>   struct cea_sad {
>   	u8 format;
> -	u8 channels; /* max number of channels - 1 */
> +	u8 channels;
>   	u8 freq;
> -	u8 byte2; /* meaning depends on format */
> +	u8 byte2;
>   };
>   
>   struct drm_encoder;


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-05-25 12:01     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:01 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   include/drm/drm_edid.h | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..37c420423625 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -359,12 +359,18 @@ struct edid {
>   
>   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
>   
> -/* Short Audio Descriptor */
> +/**
> + * struct cea_sad - Short Audio Descriptor.

Perhaps....

* struct cea_sad - CEA Short Audio Descriptor

...but that's relative to personal liking and nothing else, it's also fine as
it is, if you like it more as it is. The ball is yours :-P

Regardless of any choice about changing the description or not:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Cheers,
Angelo

> + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> + * @channels: max number of channels - 1.
> + * @freq: See CEA_SAD_FREQ_*.
> + * @byte2: meaning depends on format.
> + */
>   struct cea_sad {
>   	u8 format;
> -	u8 channels; /* max number of channels - 1 */
> +	u8 channels;
>   	u8 freq;
> -	u8 byte2; /* meaning depends on format */
> +	u8 byte2;
>   };
>   
>   struct drm_encoder;


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25 12:26     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:26 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
>   include/drm/drm_edid.h     | 14 ++++++++
>   2 files changed, 88 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 561f53831e29..61ef1b1c972c 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4758,6 +4758,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:

As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM should
never occur here?

> +	case HDMI_AUDIO_CODING_TYPE_PCM:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +

Also, I think that implementing a drm_cea_sad_get_compressed_max_bitrate()
function should be pretty straightforward... the spec says that this is
8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
so to extract it, you read byte2 and multiply it by 8000Hz.

/**
  * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
  * @sad: Pointer to the cea_sad structure
  *
  * Extracts the cea_sad byte2 field and returns the maximum bit rate
  * of a compressed audio stream.
  *
  * Note: This function may only be called for compressed audio.
  *
  * Return: Maximum bitrate of compressed audio stream in bit/s or
  *         negative number for error
  */
int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
{
	if (drm_cea_sad_is_uncompressed(sad)) {
		DRM_ERROR("Not supported: tried to get max bitrate for uncompressed format: %u\n",
			 sad->format);
		return -EINVAL;
	}

	return sad->byte2 * 8000;
}

> +/**
> + * 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 37c420423625..7a939cb95b38 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -373,6 +373,18 @@ struct cea_sad {
>   	u8 byte2;
>   };
>   
> +#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;
> @@ -380,6 +392,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);
>   


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-05-25 12:26     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:26 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
>   include/drm/drm_edid.h     | 14 ++++++++
>   2 files changed, 88 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 561f53831e29..61ef1b1c972c 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4758,6 +4758,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:

As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM should
never occur here?

> +	case HDMI_AUDIO_CODING_TYPE_PCM:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +

Also, I think that implementing a drm_cea_sad_get_compressed_max_bitrate()
function should be pretty straightforward... the spec says that this is
8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
so to extract it, you read byte2 and multiply it by 8000Hz.

/**
  * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
  * @sad: Pointer to the cea_sad structure
  *
  * Extracts the cea_sad byte2 field and returns the maximum bit rate
  * of a compressed audio stream.
  *
  * Note: This function may only be called for compressed audio.
  *
  * Return: Maximum bitrate of compressed audio stream in bit/s or
  *         negative number for error
  */
int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
{
	if (drm_cea_sad_is_uncompressed(sad)) {
		DRM_ERROR("Not supported: tried to get max bitrate for uncompressed format: %u\n",
			 sad->format);
		return -EINVAL;
	}

	return sad->byte2 * 8000;
}

> +/**
> + * 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 37c420423625..7a939cb95b38 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -373,6 +373,18 @@ struct cea_sad {
>   	u8 byte2;
>   };
>   
> +#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;
> @@ -380,6 +392,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);
>   


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-05-25 12:26     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:26 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
>   include/drm/drm_edid.h     | 14 ++++++++
>   2 files changed, 88 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 561f53831e29..61ef1b1c972c 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4758,6 +4758,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:

As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM should
never occur here?

> +	case HDMI_AUDIO_CODING_TYPE_PCM:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +

Also, I think that implementing a drm_cea_sad_get_compressed_max_bitrate()
function should be pretty straightforward... the spec says that this is
8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
so to extract it, you read byte2 and multiply it by 8000Hz.

/**
  * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
  * @sad: Pointer to the cea_sad structure
  *
  * Extracts the cea_sad byte2 field and returns the maximum bit rate
  * of a compressed audio stream.
  *
  * Note: This function may only be called for compressed audio.
  *
  * Return: Maximum bitrate of compressed audio stream in bit/s or
  *         negative number for error
  */
int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
{
	if (drm_cea_sad_is_uncompressed(sad)) {
		DRM_ERROR("Not supported: tried to get max bitrate for uncompressed format: %u\n",
			 sad->format);
		return -EINVAL;
	}

	return sad->byte2 * 8000;
}

> +/**
> + * 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 37c420423625..7a939cb95b38 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -373,6 +373,18 @@ struct cea_sad {
>   	u8 byte2;
>   };
>   
> +#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;
> @@ -380,6 +392,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);
>   


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-05-25 12:26     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:26 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
>   include/drm/drm_edid.h     | 14 ++++++++
>   2 files changed, 88 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 561f53831e29..61ef1b1c972c 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4758,6 +4758,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:

As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM should
never occur here?

> +	case HDMI_AUDIO_CODING_TYPE_PCM:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +

Also, I think that implementing a drm_cea_sad_get_compressed_max_bitrate()
function should be pretty straightforward... the spec says that this is
8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
so to extract it, you read byte2 and multiply it by 8000Hz.

/**
  * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
  * @sad: Pointer to the cea_sad structure
  *
  * Extracts the cea_sad byte2 field and returns the maximum bit rate
  * of a compressed audio stream.
  *
  * Note: This function may only be called for compressed audio.
  *
  * Return: Maximum bitrate of compressed audio stream in bit/s or
  *         negative number for error
  */
int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
{
	if (drm_cea_sad_is_uncompressed(sad)) {
		DRM_ERROR("Not supported: tried to get max bitrate for uncompressed format: %u\n",
			 sad->format);
		return -EINVAL;
	}

	return sad->byte2 * 8000;
}

> +/**
> + * 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 37c420423625..7a939cb95b38 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -373,6 +373,18 @@ struct cea_sad {
>   	u8 byte2;
>   };
>   
> +#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;
> @@ -380,6 +392,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);
>   


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-05-25 12:26     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:26 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/drm_edid.c | 74 ++++++++++++++++++++++++++++++++++++++
>   include/drm/drm_edid.h     | 14 ++++++++
>   2 files changed, 88 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 561f53831e29..61ef1b1c972c 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4758,6 +4758,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:

As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM should
never occur here?

> +	case HDMI_AUDIO_CODING_TYPE_PCM:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +

Also, I think that implementing a drm_cea_sad_get_compressed_max_bitrate()
function should be pretty straightforward... the spec says that this is
8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
so to extract it, you read byte2 and multiply it by 8000Hz.

/**
  * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
  * @sad: Pointer to the cea_sad structure
  *
  * Extracts the cea_sad byte2 field and returns the maximum bit rate
  * of a compressed audio stream.
  *
  * Note: This function may only be called for compressed audio.
  *
  * Return: Maximum bitrate of compressed audio stream in bit/s or
  *         negative number for error
  */
int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
{
	if (drm_cea_sad_is_uncompressed(sad)) {
		DRM_ERROR("Not supported: tried to get max bitrate for uncompressed format: %u\n",
			 sad->format);
		return -EINVAL;
	}

	return sad->byte2 * 8000;
}

> +/**
> + * 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 37c420423625..7a939cb95b38 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -373,6 +373,18 @@ struct cea_sad {
>   	u8 byte2;
>   };
>   
> +#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;
> @@ -380,6 +392,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);
>   


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25 12:32     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:32 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.
> 
> Also constify the frame parameter in hdmi_audio_infoframe_check() as
> it is passed to hdmi_audio_infoframe_check_only() which expects a const.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
>   include/drm/dp/drm_dp_helper.h |  2 +

this has been moved... again... this time it's include/drm/display/drm_dp_helper.h

>   include/linux/hdmi.h           |  7 ++-
>   3 files changed, 71 insertions(+), 20 deletions(-)
> 

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-05-25 12:32     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:32 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.
> 
> Also constify the frame parameter in hdmi_audio_infoframe_check() as
> it is passed to hdmi_audio_infoframe_check_only() which expects a const.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
>   include/drm/dp/drm_dp_helper.h |  2 +

this has been moved... again... this time it's include/drm/display/drm_dp_helper.h

>   include/linux/hdmi.h           |  7 ++-
>   3 files changed, 71 insertions(+), 20 deletions(-)
> 

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-05-25 12:32     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:32 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.
> 
> Also constify the frame parameter in hdmi_audio_infoframe_check() as
> it is passed to hdmi_audio_infoframe_check_only() which expects a const.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
>   include/drm/dp/drm_dp_helper.h |  2 +

this has been moved... again... this time it's include/drm/display/drm_dp_helper.h

>   include/linux/hdmi.h           |  7 ++-
>   3 files changed, 71 insertions(+), 20 deletions(-)
> 

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-05-25 12:32     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:32 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.
> 
> Also constify the frame parameter in hdmi_audio_infoframe_check() as
> it is passed to hdmi_audio_infoframe_check_only() which expects a const.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
>   include/drm/dp/drm_dp_helper.h |  2 +

this has been moved... again... this time it's include/drm/display/drm_dp_helper.h

>   include/linux/hdmi.h           |  7 ++-
>   3 files changed, 71 insertions(+), 20 deletions(-)
> 

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-05-25 12:32     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:32 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.
> 
> Also constify the frame parameter in hdmi_audio_infoframe_check() as
> it is passed to hdmi_audio_infoframe_check_only() which expects a const.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++--------
>   include/drm/dp/drm_dp_helper.h |  2 +

this has been moved... again... this time it's include/drm/display/drm_dp_helper.h

>   include/linux/hdmi.h           |  7 ++-
>   3 files changed, 71 insertions(+), 20 deletions(-)
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25 12:49     ` Maxime Ripard
  -1 siblings, 0 replies; 450+ messages in thread
From: Maxime Ripard @ 2022-05-25 12:49 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

[-- Attachment #1: Type: text/plain, Size: 2122 bytes --]

Hi,

On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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

Weren't you supposed to change it to have a separator between dp and intf?

If it's no longer in your plans, the second patch should have s/dp_intf/dpintf/

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-25 12:49     ` Maxime Ripard
  0 siblings, 0 replies; 450+ messages in thread
From: Maxime Ripard @ 2022-05-25 12:49 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev


[-- Attachment #1.1: Type: text/plain, Size: 2122 bytes --]

Hi,

On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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

Weren't you supposed to change it to have a separator between dp and intf?

If it's no longer in your plans, the second patch should have s/dp_intf/dpintf/

Maxime

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 170 bytes --]

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-25 12:49     ` Maxime Ripard
  0 siblings, 0 replies; 450+ messages in thread
From: Maxime Ripard @ 2022-05-25 12:49 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: linux-fbdev, devicetree, David Airlie, dri-devel,
	Krzysztof Kozlowski, linux-phy, Helge Deller,
	Kishon Vijay Abraham I, Chun-Kuang Hu, Jitao shi,
	Thomas Zimmermann, Markus Schneider-Pargmann, Chunfeng Yun,
	Rob Herring, linux-mediatek, Matthias Brugger, linux-arm-kernel,
	linux-kernel, Vinod Koul

[-- Attachment #1: Type: text/plain, Size: 2122 bytes --]

Hi,

On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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

Weren't you supposed to change it to have a separator between dp and intf?

If it's no longer in your plans, the second patch should have s/dp_intf/dpintf/

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-25 12:49     ` Maxime Ripard
  0 siblings, 0 replies; 450+ messages in thread
From: Maxime Ripard @ 2022-05-25 12:49 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev


[-- Attachment #1.1: Type: text/plain, Size: 2122 bytes --]

Hi,

On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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

Weren't you supposed to change it to have a separator between dp and intf?

If it's no longer in your plans, the second patch should have s/dp_intf/dpintf/

Maxime

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 112 bytes --]

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-05-25 12:49     ` Maxime Ripard
  0 siblings, 0 replies; 450+ messages in thread
From: Maxime Ripard @ 2022-05-25 12:49 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev


[-- Attachment #1.1: Type: text/plain, Size: 2122 bytes --]

Hi,

On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> DPINTF is similar to DPI but does not have the exact same feature set
> or register layouts.
> 
> DPINTF 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-----
>  1 file changed, 8 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..6d9f6c11806e 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/DPINTF Controller
>  
>  maintainers:
>    - CK Hu <ck.hu@mediatek.com>
>    - Jitao shi <jitao.shi@mediatek.com>
>  
>  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 DPINTF 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

Weren't you supposed to change it to have a separator between dp and intf?

If it's no longer in your plans, the second patch should have s/dp_intf/dpintf/

Maxime

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25 12:58     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:58 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <jason-jh.lin@mediatek.com>.
> 

Only after finishing the review, I've noticed that I just wrote the same things
that I wrote in my review for version 8... and if I recall correctly, this is not
the first time that something like that happens.

Please pay attention to what reviewers say, as to not waste anyone's time.


> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   
> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;
> @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   
>   	vm.pixelclock = pll_rate / factor;
>   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {

The indentation was perfect before that change...

>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> -	else
> +	} else {
>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> -
> +	}
>   
>   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
>   
> @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
>   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> -	hsync.sync_width = vm.hsync_len;
> -	hsync.back_porch = vm.hback_porch;
> -	hsync.front_porch = vm.hfront_porch;
> +	if (dpi->conf->is_dpintf) {
> +		hsync.sync_width = vm.hsync_len / 4;
> +		hsync.back_porch = vm.hback_porch / 4;
> +		hsync.front_porch = vm.hfront_porch / 4;
> +	} else {
> +		hsync.sync_width = vm.hsync_len;
> +		hsync.back_porch = vm.hback_porch;
> +		hsync.front_porch = vm.hfront_porch;
> +	}

This looks way better:

	hsync.sync_width = vm.hsync_len;
	hsync.back_porch = vm.hback_porch;
	hsync.front_porch = vm.hfront_porch;

	/* For DPINTF, we need to divide everything by 4 .. lanes? */
	if (dpi->conf->is_dpintf) {
		hsync.sync_width /= 4;
		hsync.back_porch /= 4;
		hsync.front_porch /= 4;
	}

>   	hsync.shift_half_line = false;
>   	vsync_lodd.sync_width = vm.vsync_len;
>   	vsync_lodd.back_porch = vm.vback_porch;
> @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   	mtk_dpi_config_channel_limit(dpi);
>   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
>   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> -	mtk_dpi_config_2n_h_fre(dpi);
> -	mtk_dpi_dual_edge(dpi);
> -	mtk_dpi_config_disable_edge(dpi);
> +	if (dpi->conf->is_dpintf) {
> +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> +			     DPINTF_INPUT_2P_EN);
> +	} else {
> +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> +		mtk_dpi_config_2n_h_fre(dpi);
> +		mtk_dpi_dual_edge(dpi);
> +		mtk_dpi_config_disable_edge(dpi);
> +	}
>   	mtk_dpi_sw_reset(dpi, false);
>   
> +	mtk_dpi_enable(dpi);
> +
>   	return 0;
>   }
>   
> @@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>   	u32 *input_fmts;
>   
>   	*num_input_fmts = 0;
> -

Removing this line is not part of adding dpintf support, so don't do that.

>   	input_fmts = kcalloc(1, sizeof(*input_fmts),
>   			     GFP_KERNEL);
>   	if (!input_fmts)
> @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
>   		if (dpi->conf->num_output_fmts)
>   			out_bus_format = dpi->conf->output_fmts[0];
>   
> -	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> -		bridge_state->input_bus_cfg.format,
> -		bridge_state->output_bus_cfg.format);
> +	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> +		 bridge_state->input_bus_cfg.format,
> +		 bridge_state->output_bus_cfg.format);

This message is not giving any constantly changing information, nor any one that
is interesting for the user: keep this as dev_dbg().

>   
>   	dpi->output_fmt = out_bus_format;
>   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
>   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
>   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> +	else
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
>   
>   	return 0;
>   }
> @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
>   {
>   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>   
> -	if (mode->clock > dpi->conf->max_clock_khz)
> +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
>   		return MODE_CLOCK_HIGH;
>   
>   	return MODE_OK;
> @@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
>   		return 2;
>   }
>   
> +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> +{
> +	if (clock < 70000)

is 70000 intentional? Or did you mean 700000?

> +		return 4;
> +	else if (clock < 200000)
> +		return 2;
> +	else
> +		return 1;
> +}
> +
>   static const u32 mt8173_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_1X24,
>   };
> @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_2X12_BE,
>   };
>   
> +static const u32 mt8195_output_fmts[] = {
> +	MEDIA_BUS_FMT_RGB888_1X24,
> +	MEDIA_BUS_FMT_YUV8_1X24,
> +	MEDIA_BUS_FMT_YUYV8_1X16,
> +};
> +
>   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.c_bottom = 0x0010,
>   	.c_top = 0x0FE0,
> @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.y_top = 0x0FE0,
>   };
>   
> +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> +	.c_bottom = 0x0000,
> +	.c_top = 0xFFF,
> +	.y_bottom = 0x0000,
> +	.y_top = 0xFFF,
> +};
> +
>   static const struct mtk_dpi_conf mt8173_conf = {
>   	.cal_factor = mt8173_calculate_factor,
>   	.reg_h_fre_con = 0xe0,
> @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
>   	.limit = &mtk_dpi_limit,
>   };
>   
> +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> +	.cal_factor = mt8195_dpintf_calculate_factor,
> +	.output_fmts = mt8195_output_fmts,
> +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> +	.is_dpintf = true,
> +	.dimension_mask = DPINTF_HPW_MASK,
> +	.hvsize_mask = DPINTF_HSIZE_MASK,
> +	.channel_swap_shift = DPINTF_CH_SWAP,
> +	.yuv422_en_bit = DPINTF_YUV422_EN,
> +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> +	.limit = &mtk_dpintf_limit,
> +};
> +
>   static int mtk_dpi_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>   	if (IS_ERR(dpi->engine_clk)) {
>   		ret = PTR_ERR(dpi->engine_clk);
>   		if (ret != -EPROBE_DEFER)
> -			dev_err(dev, "Failed to get engine clock: %d\n", ret);
> +			dev_err(dev, "Failed to get engine clock: %d\n",
> +				ret);

Why are you breaking this line?

> +
> +		return ret;
> +	}
> +
> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
> +				ret);
> +
> +		return ret;
> +	}
> +

You're getting this clock twice, what happened here?

P.S.: As I explained on the dt-bindings patch, you likely don't even need this
       clock at all.

> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
>   
>   		return ret;
>   	}
> @@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>   	{ .compatible = "mediatek,mt8192-dpi",
>   	  .data = &mt8192_conf,
>   	},
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = &mt8195_dpintf_conf,
> +	},
>   	{ },
>   };
>   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index 3a02fabe1662..dd47dd3f2e4f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -40,10 +40,15 @@
>   #define FAKE_DE_LEVEN			BIT(21)
>   #define FAKE_DE_RODD			BIT(22)
>   #define FAKE_DE_REVEN			BIT(23)
> +#define DPINTF_YUV422_EN		BIT(24)
> +#define DPINTF_CSC_ENABLE		BIT(26)
> +#define DPINTF_INPUT_2P_EN		BIT(29)
>   
>   #define DPI_OUTPUT_SETTING	0x14
>   #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>   #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
>   #define SWAP_RGB			0x00
>   #define SWAP_GBR			0x01
>   #define SWAP_BRG			0x02
> @@ -80,8 +85,10 @@
>   #define DPI_SIZE		0x18
>   #define HSIZE				0
>   #define HSIZE_MASK			(0x1FFF << 0)
> +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
>   #define VSIZE				16
>   #define VSIZE_MASK			(0x1FFF << 16)
> +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
>   
>   #define DPI_DDR_SETTING		0x1C
>   #define DDR_EN				BIT(0)
> @@ -93,24 +100,30 @@
>   #define DPI_TGEN_HWIDTH		0x20
>   #define HPW				0
>   #define HPW_MASK			(0xFFF << 0)
> +#define DPINTF_HPW_MASK			(0xFFFF << 0)
>   
>   #define DPI_TGEN_HPORCH		0x24
>   #define HBP				0
>   #define HBP_MASK			(0xFFF << 0)
> +#define DPINTF_HBP_MASK			(0xFFFF << 0)
>   #define HFP				16
>   #define HFP_MASK			(0xFFF << 16)
> +#define DPINTF_HFP_MASK			(0xFFFF << 16)
>   
>   #define DPI_TGEN_VWIDTH		0x28
>   #define DPI_TGEN_VPORCH		0x2C
>   
>   #define VSYNC_WIDTH_SHIFT		0
>   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
>   #define VSYNC_HALF_LINE_SHIFT		16
>   #define VSYNC_HALF_LINE_MASK		BIT(16)
>   #define VSYNC_BACK_PORCH_SHIFT		0
>   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
>   #define VSYNC_FRONT_PORCH_SHIFT		16
>   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
>   
>   #define DPI_BG_HCNTL		0x30
>   #define BG_RIGHT			(0x1FFF << 0)
> @@ -217,4 +230,26 @@
>   
>   #define EDGE_SEL_EN			BIT(5)
>   #define H_FRE_2N			BIT(25)
> +
> +#define RGB_TO_JPEG			0x00

This is 0x0

> +#define RGB_TO_FULL709			0x01

0x1

> +#define RGB_TO_BT601			0x02

0x2

...remove the unnecessary leading zeros, but... you're not ever
using this set of definitions, so why are you even adding them?

> +#define RGB_TO_BT709			0x03
> +#define JPEG_TO_RGB			0x04
> +#define FULL709_TO_RGB			0x05
> +#define BT601_TO_RGB			0x06
> +#define BT709_TO_RGB			0x07
> +#define JPEG_TO_BT601			0x08
> +#define JPEG_TO_BT709			0x09
> +#define BT601_TO_JPEG			0xA
> +#define BT709_TO_JPEG			0xB
> +#define BT709_TO_BT601			0xC
> +#define BT601_TO_BT709			0xD
> +#define JPEG_TO_CERGB			0x14
> +#define FULL709_TO_CERGB		0x15
> +#define BT601_TO_CERGB			0x16
> +#define BT709_TO_CERGB			0x17
> +#define RGB_TO_CERGB			0x1C
> +#define MATRIX_BIT			BIT(8)
> +#define EXT_MATRIX_EN			BIT(12)
>   #endif /* __MTK_DPI_REGS_H */
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 245d0074e12d..3738665a712e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>   	[MTK_DISP_WDMA] = "wdma",
>   	[MTK_DPI] = "dpi",
>   	[MTK_DSI] = "dsi",
> +	[MTK_DP_INTF] = "dp-intf",
> +	[MTK_DISP_PWM] = "pwm",
> +	[MTK_DISP_MUTEX] = "mutex",
> +	[MTK_DISP_OD] = "od",
> +	[MTK_DISP_BLS] = "bls",

Please keep alphabetic order.

>   };
>   
>   struct mtk_ddp_comp_match {
> @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
>   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
>   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
> +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
> +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },

Indentation issue. Fix it.

>   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
>   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
>   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
> @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>   	    type == MTK_DISP_PWM ||
>   	    type == MTK_DISP_RDMA ||
>   	    type == MTK_DPI ||
> +	    type == MTK_DP_INTF ||
>   	    type == MTK_DSI)
>   		return 0;
>   
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 825d763d2378..c4e683f46a95 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
>   	MTK_DISP_UFOE,
>   	MTK_DISP_WDMA,
>   	MTK_DPI,
> +	MTK_DP_INTF,
>   	MTK_DSI,
>   	MTK_DDP_COMP_TYPE_MAX,
>   };
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index a2a783fc580e..e25ac61aac08 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>   	  .data = (void *)MTK_DPI },
>   	{ .compatible = "mediatek,mt8183-dpi",
>   	  .data = (void *)MTK_DPI },
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = (void *)MTK_DP_INTF },
>   	{ .compatible = "mediatek,mt2701-dsi",
>   	  .data = (void *)MTK_DSI },
>   	{ .compatible = "mediatek,mt8173-dsi",
> @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
>   		    comp_type == MTK_DISP_OVL_2L ||
>   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
>   		    comp_type == MTK_DISP_RDMA ||
> +		    comp_type == MTK_DSI ||
>   		    comp_type == MTK_DPI ||
> -		    comp_type == MTK_DSI) {
> +		    comp_type == MTK_DP_INTF) {

These were nice and alphabetically ordered, why are you moving MTK_DSI up there?!

  		    comp_type == MTK_DISP_RDMA ||
		    comp_type == MTK_DP_INTF ||
  		    comp_type == MTK_DPI ||
		    comp_type == MTK_DSI) {

... that's how it should look like.

>   			dev_info(dev, "Adding component match for %pOF\n",
>   				 node);
>   			drm_of_component_match_add(dev, &match, component_compare_of,
> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
> index 3e998bfb795a..e4b84c347201 100644
> --- a/include/linux/soc/mediatek/mtk-mmsys.h
> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
>   	DDP_COMPONENT_COLOR0,
>   	DDP_COMPONENT_COLOR1,
>   	DDP_COMPONENT_DITHER,
> -	DDP_COMPONENT_DP_INTF0,
> -	DDP_COMPONENT_DP_INTF1,
>   	DDP_COMPONENT_DPI0,
>   	DDP_COMPONENT_DPI1,
>   	DDP_COMPONENT_DSC0,
>   	DDP_COMPONENT_DSC1,
> +	DDP_COMPONENT_DP_INTF0,
> +	DDP_COMPONENT_DP_INTF1,

Why are you moving this?!

>   	DDP_COMPONENT_DSI0,
>   	DDP_COMPONENT_DSI1,
>   	DDP_COMPONENT_DSI2,



^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-05-25 12:58     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:58 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <jason-jh.lin@mediatek.com>.
> 

Only after finishing the review, I've noticed that I just wrote the same things
that I wrote in my review for version 8... and if I recall correctly, this is not
the first time that something like that happens.

Please pay attention to what reviewers say, as to not waste anyone's time.


> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   
> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;
> @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   
>   	vm.pixelclock = pll_rate / factor;
>   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {

The indentation was perfect before that change...

>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> -	else
> +	} else {
>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> -
> +	}
>   
>   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
>   
> @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
>   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> -	hsync.sync_width = vm.hsync_len;
> -	hsync.back_porch = vm.hback_porch;
> -	hsync.front_porch = vm.hfront_porch;
> +	if (dpi->conf->is_dpintf) {
> +		hsync.sync_width = vm.hsync_len / 4;
> +		hsync.back_porch = vm.hback_porch / 4;
> +		hsync.front_porch = vm.hfront_porch / 4;
> +	} else {
> +		hsync.sync_width = vm.hsync_len;
> +		hsync.back_porch = vm.hback_porch;
> +		hsync.front_porch = vm.hfront_porch;
> +	}

This looks way better:

	hsync.sync_width = vm.hsync_len;
	hsync.back_porch = vm.hback_porch;
	hsync.front_porch = vm.hfront_porch;

	/* For DPINTF, we need to divide everything by 4 .. lanes? */
	if (dpi->conf->is_dpintf) {
		hsync.sync_width /= 4;
		hsync.back_porch /= 4;
		hsync.front_porch /= 4;
	}

>   	hsync.shift_half_line = false;
>   	vsync_lodd.sync_width = vm.vsync_len;
>   	vsync_lodd.back_porch = vm.vback_porch;
> @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   	mtk_dpi_config_channel_limit(dpi);
>   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
>   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> -	mtk_dpi_config_2n_h_fre(dpi);
> -	mtk_dpi_dual_edge(dpi);
> -	mtk_dpi_config_disable_edge(dpi);
> +	if (dpi->conf->is_dpintf) {
> +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> +			     DPINTF_INPUT_2P_EN);
> +	} else {
> +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> +		mtk_dpi_config_2n_h_fre(dpi);
> +		mtk_dpi_dual_edge(dpi);
> +		mtk_dpi_config_disable_edge(dpi);
> +	}
>   	mtk_dpi_sw_reset(dpi, false);
>   
> +	mtk_dpi_enable(dpi);
> +
>   	return 0;
>   }
>   
> @@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>   	u32 *input_fmts;
>   
>   	*num_input_fmts = 0;
> -

Removing this line is not part of adding dpintf support, so don't do that.

>   	input_fmts = kcalloc(1, sizeof(*input_fmts),
>   			     GFP_KERNEL);
>   	if (!input_fmts)
> @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
>   		if (dpi->conf->num_output_fmts)
>   			out_bus_format = dpi->conf->output_fmts[0];
>   
> -	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> -		bridge_state->input_bus_cfg.format,
> -		bridge_state->output_bus_cfg.format);
> +	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> +		 bridge_state->input_bus_cfg.format,
> +		 bridge_state->output_bus_cfg.format);

This message is not giving any constantly changing information, nor any one that
is interesting for the user: keep this as dev_dbg().

>   
>   	dpi->output_fmt = out_bus_format;
>   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
>   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
>   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> +	else
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
>   
>   	return 0;
>   }
> @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
>   {
>   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>   
> -	if (mode->clock > dpi->conf->max_clock_khz)
> +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
>   		return MODE_CLOCK_HIGH;
>   
>   	return MODE_OK;
> @@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
>   		return 2;
>   }
>   
> +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> +{
> +	if (clock < 70000)

is 70000 intentional? Or did you mean 700000?

> +		return 4;
> +	else if (clock < 200000)
> +		return 2;
> +	else
> +		return 1;
> +}
> +
>   static const u32 mt8173_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_1X24,
>   };
> @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_2X12_BE,
>   };
>   
> +static const u32 mt8195_output_fmts[] = {
> +	MEDIA_BUS_FMT_RGB888_1X24,
> +	MEDIA_BUS_FMT_YUV8_1X24,
> +	MEDIA_BUS_FMT_YUYV8_1X16,
> +};
> +
>   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.c_bottom = 0x0010,
>   	.c_top = 0x0FE0,
> @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.y_top = 0x0FE0,
>   };
>   
> +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> +	.c_bottom = 0x0000,
> +	.c_top = 0xFFF,
> +	.y_bottom = 0x0000,
> +	.y_top = 0xFFF,
> +};
> +
>   static const struct mtk_dpi_conf mt8173_conf = {
>   	.cal_factor = mt8173_calculate_factor,
>   	.reg_h_fre_con = 0xe0,
> @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
>   	.limit = &mtk_dpi_limit,
>   };
>   
> +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> +	.cal_factor = mt8195_dpintf_calculate_factor,
> +	.output_fmts = mt8195_output_fmts,
> +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> +	.is_dpintf = true,
> +	.dimension_mask = DPINTF_HPW_MASK,
> +	.hvsize_mask = DPINTF_HSIZE_MASK,
> +	.channel_swap_shift = DPINTF_CH_SWAP,
> +	.yuv422_en_bit = DPINTF_YUV422_EN,
> +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> +	.limit = &mtk_dpintf_limit,
> +};
> +
>   static int mtk_dpi_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>   	if (IS_ERR(dpi->engine_clk)) {
>   		ret = PTR_ERR(dpi->engine_clk);
>   		if (ret != -EPROBE_DEFER)
> -			dev_err(dev, "Failed to get engine clock: %d\n", ret);
> +			dev_err(dev, "Failed to get engine clock: %d\n",
> +				ret);

Why are you breaking this line?

> +
> +		return ret;
> +	}
> +
> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
> +				ret);
> +
> +		return ret;
> +	}
> +

You're getting this clock twice, what happened here?

P.S.: As I explained on the dt-bindings patch, you likely don't even need this
       clock at all.

> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
>   
>   		return ret;
>   	}
> @@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>   	{ .compatible = "mediatek,mt8192-dpi",
>   	  .data = &mt8192_conf,
>   	},
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = &mt8195_dpintf_conf,
> +	},
>   	{ },
>   };
>   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index 3a02fabe1662..dd47dd3f2e4f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -40,10 +40,15 @@
>   #define FAKE_DE_LEVEN			BIT(21)
>   #define FAKE_DE_RODD			BIT(22)
>   #define FAKE_DE_REVEN			BIT(23)
> +#define DPINTF_YUV422_EN		BIT(24)
> +#define DPINTF_CSC_ENABLE		BIT(26)
> +#define DPINTF_INPUT_2P_EN		BIT(29)
>   
>   #define DPI_OUTPUT_SETTING	0x14
>   #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>   #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
>   #define SWAP_RGB			0x00
>   #define SWAP_GBR			0x01
>   #define SWAP_BRG			0x02
> @@ -80,8 +85,10 @@
>   #define DPI_SIZE		0x18
>   #define HSIZE				0
>   #define HSIZE_MASK			(0x1FFF << 0)
> +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
>   #define VSIZE				16
>   #define VSIZE_MASK			(0x1FFF << 16)
> +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
>   
>   #define DPI_DDR_SETTING		0x1C
>   #define DDR_EN				BIT(0)
> @@ -93,24 +100,30 @@
>   #define DPI_TGEN_HWIDTH		0x20
>   #define HPW				0
>   #define HPW_MASK			(0xFFF << 0)
> +#define DPINTF_HPW_MASK			(0xFFFF << 0)
>   
>   #define DPI_TGEN_HPORCH		0x24
>   #define HBP				0
>   #define HBP_MASK			(0xFFF << 0)
> +#define DPINTF_HBP_MASK			(0xFFFF << 0)
>   #define HFP				16
>   #define HFP_MASK			(0xFFF << 16)
> +#define DPINTF_HFP_MASK			(0xFFFF << 16)
>   
>   #define DPI_TGEN_VWIDTH		0x28
>   #define DPI_TGEN_VPORCH		0x2C
>   
>   #define VSYNC_WIDTH_SHIFT		0
>   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
>   #define VSYNC_HALF_LINE_SHIFT		16
>   #define VSYNC_HALF_LINE_MASK		BIT(16)
>   #define VSYNC_BACK_PORCH_SHIFT		0
>   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
>   #define VSYNC_FRONT_PORCH_SHIFT		16
>   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
>   
>   #define DPI_BG_HCNTL		0x30
>   #define BG_RIGHT			(0x1FFF << 0)
> @@ -217,4 +230,26 @@
>   
>   #define EDGE_SEL_EN			BIT(5)
>   #define H_FRE_2N			BIT(25)
> +
> +#define RGB_TO_JPEG			0x00

This is 0x0

> +#define RGB_TO_FULL709			0x01

0x1

> +#define RGB_TO_BT601			0x02

0x2

...remove the unnecessary leading zeros, but... you're not ever
using this set of definitions, so why are you even adding them?

> +#define RGB_TO_BT709			0x03
> +#define JPEG_TO_RGB			0x04
> +#define FULL709_TO_RGB			0x05
> +#define BT601_TO_RGB			0x06
> +#define BT709_TO_RGB			0x07
> +#define JPEG_TO_BT601			0x08
> +#define JPEG_TO_BT709			0x09
> +#define BT601_TO_JPEG			0xA
> +#define BT709_TO_JPEG			0xB
> +#define BT709_TO_BT601			0xC
> +#define BT601_TO_BT709			0xD
> +#define JPEG_TO_CERGB			0x14
> +#define FULL709_TO_CERGB		0x15
> +#define BT601_TO_CERGB			0x16
> +#define BT709_TO_CERGB			0x17
> +#define RGB_TO_CERGB			0x1C
> +#define MATRIX_BIT			BIT(8)
> +#define EXT_MATRIX_EN			BIT(12)
>   #endif /* __MTK_DPI_REGS_H */
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 245d0074e12d..3738665a712e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>   	[MTK_DISP_WDMA] = "wdma",
>   	[MTK_DPI] = "dpi",
>   	[MTK_DSI] = "dsi",
> +	[MTK_DP_INTF] = "dp-intf",
> +	[MTK_DISP_PWM] = "pwm",
> +	[MTK_DISP_MUTEX] = "mutex",
> +	[MTK_DISP_OD] = "od",
> +	[MTK_DISP_BLS] = "bls",

Please keep alphabetic order.

>   };
>   
>   struct mtk_ddp_comp_match {
> @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
>   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
>   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
> +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
> +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },

Indentation issue. Fix it.

>   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
>   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
>   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
> @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>   	    type == MTK_DISP_PWM ||
>   	    type == MTK_DISP_RDMA ||
>   	    type == MTK_DPI ||
> +	    type == MTK_DP_INTF ||
>   	    type == MTK_DSI)
>   		return 0;
>   
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 825d763d2378..c4e683f46a95 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
>   	MTK_DISP_UFOE,
>   	MTK_DISP_WDMA,
>   	MTK_DPI,
> +	MTK_DP_INTF,
>   	MTK_DSI,
>   	MTK_DDP_COMP_TYPE_MAX,
>   };
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index a2a783fc580e..e25ac61aac08 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>   	  .data = (void *)MTK_DPI },
>   	{ .compatible = "mediatek,mt8183-dpi",
>   	  .data = (void *)MTK_DPI },
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = (void *)MTK_DP_INTF },
>   	{ .compatible = "mediatek,mt2701-dsi",
>   	  .data = (void *)MTK_DSI },
>   	{ .compatible = "mediatek,mt8173-dsi",
> @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
>   		    comp_type == MTK_DISP_OVL_2L ||
>   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
>   		    comp_type == MTK_DISP_RDMA ||
> +		    comp_type == MTK_DSI ||
>   		    comp_type == MTK_DPI ||
> -		    comp_type == MTK_DSI) {
> +		    comp_type == MTK_DP_INTF) {

These were nice and alphabetically ordered, why are you moving MTK_DSI up there?!

  		    comp_type == MTK_DISP_RDMA ||
		    comp_type == MTK_DP_INTF ||
  		    comp_type == MTK_DPI ||
		    comp_type == MTK_DSI) {

... that's how it should look like.

>   			dev_info(dev, "Adding component match for %pOF\n",
>   				 node);
>   			drm_of_component_match_add(dev, &match, component_compare_of,
> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
> index 3e998bfb795a..e4b84c347201 100644
> --- a/include/linux/soc/mediatek/mtk-mmsys.h
> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
>   	DDP_COMPONENT_COLOR0,
>   	DDP_COMPONENT_COLOR1,
>   	DDP_COMPONENT_DITHER,
> -	DDP_COMPONENT_DP_INTF0,
> -	DDP_COMPONENT_DP_INTF1,
>   	DDP_COMPONENT_DPI0,
>   	DDP_COMPONENT_DPI1,
>   	DDP_COMPONENT_DSC0,
>   	DDP_COMPONENT_DSC1,
> +	DDP_COMPONENT_DP_INTF0,
> +	DDP_COMPONENT_DP_INTF1,

Why are you moving this?!

>   	DDP_COMPONENT_DSI0,
>   	DDP_COMPONENT_DSI1,
>   	DDP_COMPONENT_DSI2,



^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-05-25 12:58     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:58 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <jason-jh.lin@mediatek.com>.
> 

Only after finishing the review, I've noticed that I just wrote the same things
that I wrote in my review for version 8... and if I recall correctly, this is not
the first time that something like that happens.

Please pay attention to what reviewers say, as to not waste anyone's time.


> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   
> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;
> @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   
>   	vm.pixelclock = pll_rate / factor;
>   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {

The indentation was perfect before that change...

>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> -	else
> +	} else {
>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> -
> +	}
>   
>   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
>   
> @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
>   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> -	hsync.sync_width = vm.hsync_len;
> -	hsync.back_porch = vm.hback_porch;
> -	hsync.front_porch = vm.hfront_porch;
> +	if (dpi->conf->is_dpintf) {
> +		hsync.sync_width = vm.hsync_len / 4;
> +		hsync.back_porch = vm.hback_porch / 4;
> +		hsync.front_porch = vm.hfront_porch / 4;
> +	} else {
> +		hsync.sync_width = vm.hsync_len;
> +		hsync.back_porch = vm.hback_porch;
> +		hsync.front_porch = vm.hfront_porch;
> +	}

This looks way better:

	hsync.sync_width = vm.hsync_len;
	hsync.back_porch = vm.hback_porch;
	hsync.front_porch = vm.hfront_porch;

	/* For DPINTF, we need to divide everything by 4 .. lanes? */
	if (dpi->conf->is_dpintf) {
		hsync.sync_width /= 4;
		hsync.back_porch /= 4;
		hsync.front_porch /= 4;
	}

>   	hsync.shift_half_line = false;
>   	vsync_lodd.sync_width = vm.vsync_len;
>   	vsync_lodd.back_porch = vm.vback_porch;
> @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   	mtk_dpi_config_channel_limit(dpi);
>   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
>   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> -	mtk_dpi_config_2n_h_fre(dpi);
> -	mtk_dpi_dual_edge(dpi);
> -	mtk_dpi_config_disable_edge(dpi);
> +	if (dpi->conf->is_dpintf) {
> +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> +			     DPINTF_INPUT_2P_EN);
> +	} else {
> +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> +		mtk_dpi_config_2n_h_fre(dpi);
> +		mtk_dpi_dual_edge(dpi);
> +		mtk_dpi_config_disable_edge(dpi);
> +	}
>   	mtk_dpi_sw_reset(dpi, false);
>   
> +	mtk_dpi_enable(dpi);
> +
>   	return 0;
>   }
>   
> @@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>   	u32 *input_fmts;
>   
>   	*num_input_fmts = 0;
> -

Removing this line is not part of adding dpintf support, so don't do that.

>   	input_fmts = kcalloc(1, sizeof(*input_fmts),
>   			     GFP_KERNEL);
>   	if (!input_fmts)
> @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
>   		if (dpi->conf->num_output_fmts)
>   			out_bus_format = dpi->conf->output_fmts[0];
>   
> -	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> -		bridge_state->input_bus_cfg.format,
> -		bridge_state->output_bus_cfg.format);
> +	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> +		 bridge_state->input_bus_cfg.format,
> +		 bridge_state->output_bus_cfg.format);

This message is not giving any constantly changing information, nor any one that
is interesting for the user: keep this as dev_dbg().

>   
>   	dpi->output_fmt = out_bus_format;
>   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
>   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
>   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> +	else
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
>   
>   	return 0;
>   }
> @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
>   {
>   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>   
> -	if (mode->clock > dpi->conf->max_clock_khz)
> +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
>   		return MODE_CLOCK_HIGH;
>   
>   	return MODE_OK;
> @@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
>   		return 2;
>   }
>   
> +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> +{
> +	if (clock < 70000)

is 70000 intentional? Or did you mean 700000?

> +		return 4;
> +	else if (clock < 200000)
> +		return 2;
> +	else
> +		return 1;
> +}
> +
>   static const u32 mt8173_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_1X24,
>   };
> @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_2X12_BE,
>   };
>   
> +static const u32 mt8195_output_fmts[] = {
> +	MEDIA_BUS_FMT_RGB888_1X24,
> +	MEDIA_BUS_FMT_YUV8_1X24,
> +	MEDIA_BUS_FMT_YUYV8_1X16,
> +};
> +
>   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.c_bottom = 0x0010,
>   	.c_top = 0x0FE0,
> @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.y_top = 0x0FE0,
>   };
>   
> +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> +	.c_bottom = 0x0000,
> +	.c_top = 0xFFF,
> +	.y_bottom = 0x0000,
> +	.y_top = 0xFFF,
> +};
> +
>   static const struct mtk_dpi_conf mt8173_conf = {
>   	.cal_factor = mt8173_calculate_factor,
>   	.reg_h_fre_con = 0xe0,
> @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
>   	.limit = &mtk_dpi_limit,
>   };
>   
> +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> +	.cal_factor = mt8195_dpintf_calculate_factor,
> +	.output_fmts = mt8195_output_fmts,
> +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> +	.is_dpintf = true,
> +	.dimension_mask = DPINTF_HPW_MASK,
> +	.hvsize_mask = DPINTF_HSIZE_MASK,
> +	.channel_swap_shift = DPINTF_CH_SWAP,
> +	.yuv422_en_bit = DPINTF_YUV422_EN,
> +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> +	.limit = &mtk_dpintf_limit,
> +};
> +
>   static int mtk_dpi_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>   	if (IS_ERR(dpi->engine_clk)) {
>   		ret = PTR_ERR(dpi->engine_clk);
>   		if (ret != -EPROBE_DEFER)
> -			dev_err(dev, "Failed to get engine clock: %d\n", ret);
> +			dev_err(dev, "Failed to get engine clock: %d\n",
> +				ret);

Why are you breaking this line?

> +
> +		return ret;
> +	}
> +
> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
> +				ret);
> +
> +		return ret;
> +	}
> +

You're getting this clock twice, what happened here?

P.S.: As I explained on the dt-bindings patch, you likely don't even need this
       clock at all.

> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
>   
>   		return ret;
>   	}
> @@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>   	{ .compatible = "mediatek,mt8192-dpi",
>   	  .data = &mt8192_conf,
>   	},
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = &mt8195_dpintf_conf,
> +	},
>   	{ },
>   };
>   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index 3a02fabe1662..dd47dd3f2e4f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -40,10 +40,15 @@
>   #define FAKE_DE_LEVEN			BIT(21)
>   #define FAKE_DE_RODD			BIT(22)
>   #define FAKE_DE_REVEN			BIT(23)
> +#define DPINTF_YUV422_EN		BIT(24)
> +#define DPINTF_CSC_ENABLE		BIT(26)
> +#define DPINTF_INPUT_2P_EN		BIT(29)
>   
>   #define DPI_OUTPUT_SETTING	0x14
>   #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>   #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
>   #define SWAP_RGB			0x00
>   #define SWAP_GBR			0x01
>   #define SWAP_BRG			0x02
> @@ -80,8 +85,10 @@
>   #define DPI_SIZE		0x18
>   #define HSIZE				0
>   #define HSIZE_MASK			(0x1FFF << 0)
> +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
>   #define VSIZE				16
>   #define VSIZE_MASK			(0x1FFF << 16)
> +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
>   
>   #define DPI_DDR_SETTING		0x1C
>   #define DDR_EN				BIT(0)
> @@ -93,24 +100,30 @@
>   #define DPI_TGEN_HWIDTH		0x20
>   #define HPW				0
>   #define HPW_MASK			(0xFFF << 0)
> +#define DPINTF_HPW_MASK			(0xFFFF << 0)
>   
>   #define DPI_TGEN_HPORCH		0x24
>   #define HBP				0
>   #define HBP_MASK			(0xFFF << 0)
> +#define DPINTF_HBP_MASK			(0xFFFF << 0)
>   #define HFP				16
>   #define HFP_MASK			(0xFFF << 16)
> +#define DPINTF_HFP_MASK			(0xFFFF << 16)
>   
>   #define DPI_TGEN_VWIDTH		0x28
>   #define DPI_TGEN_VPORCH		0x2C
>   
>   #define VSYNC_WIDTH_SHIFT		0
>   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
>   #define VSYNC_HALF_LINE_SHIFT		16
>   #define VSYNC_HALF_LINE_MASK		BIT(16)
>   #define VSYNC_BACK_PORCH_SHIFT		0
>   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
>   #define VSYNC_FRONT_PORCH_SHIFT		16
>   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
>   
>   #define DPI_BG_HCNTL		0x30
>   #define BG_RIGHT			(0x1FFF << 0)
> @@ -217,4 +230,26 @@
>   
>   #define EDGE_SEL_EN			BIT(5)
>   #define H_FRE_2N			BIT(25)
> +
> +#define RGB_TO_JPEG			0x00

This is 0x0

> +#define RGB_TO_FULL709			0x01

0x1

> +#define RGB_TO_BT601			0x02

0x2

...remove the unnecessary leading zeros, but... you're not ever
using this set of definitions, so why are you even adding them?

> +#define RGB_TO_BT709			0x03
> +#define JPEG_TO_RGB			0x04
> +#define FULL709_TO_RGB			0x05
> +#define BT601_TO_RGB			0x06
> +#define BT709_TO_RGB			0x07
> +#define JPEG_TO_BT601			0x08
> +#define JPEG_TO_BT709			0x09
> +#define BT601_TO_JPEG			0xA
> +#define BT709_TO_JPEG			0xB
> +#define BT709_TO_BT601			0xC
> +#define BT601_TO_BT709			0xD
> +#define JPEG_TO_CERGB			0x14
> +#define FULL709_TO_CERGB		0x15
> +#define BT601_TO_CERGB			0x16
> +#define BT709_TO_CERGB			0x17
> +#define RGB_TO_CERGB			0x1C
> +#define MATRIX_BIT			BIT(8)
> +#define EXT_MATRIX_EN			BIT(12)
>   #endif /* __MTK_DPI_REGS_H */
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 245d0074e12d..3738665a712e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>   	[MTK_DISP_WDMA] = "wdma",
>   	[MTK_DPI] = "dpi",
>   	[MTK_DSI] = "dsi",
> +	[MTK_DP_INTF] = "dp-intf",
> +	[MTK_DISP_PWM] = "pwm",
> +	[MTK_DISP_MUTEX] = "mutex",
> +	[MTK_DISP_OD] = "od",
> +	[MTK_DISP_BLS] = "bls",

Please keep alphabetic order.

>   };
>   
>   struct mtk_ddp_comp_match {
> @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
>   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
>   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
> +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
> +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },

Indentation issue. Fix it.

>   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
>   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
>   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
> @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>   	    type == MTK_DISP_PWM ||
>   	    type == MTK_DISP_RDMA ||
>   	    type == MTK_DPI ||
> +	    type == MTK_DP_INTF ||
>   	    type == MTK_DSI)
>   		return 0;
>   
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 825d763d2378..c4e683f46a95 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
>   	MTK_DISP_UFOE,
>   	MTK_DISP_WDMA,
>   	MTK_DPI,
> +	MTK_DP_INTF,
>   	MTK_DSI,
>   	MTK_DDP_COMP_TYPE_MAX,
>   };
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index a2a783fc580e..e25ac61aac08 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>   	  .data = (void *)MTK_DPI },
>   	{ .compatible = "mediatek,mt8183-dpi",
>   	  .data = (void *)MTK_DPI },
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = (void *)MTK_DP_INTF },
>   	{ .compatible = "mediatek,mt2701-dsi",
>   	  .data = (void *)MTK_DSI },
>   	{ .compatible = "mediatek,mt8173-dsi",
> @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
>   		    comp_type == MTK_DISP_OVL_2L ||
>   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
>   		    comp_type == MTK_DISP_RDMA ||
> +		    comp_type == MTK_DSI ||
>   		    comp_type == MTK_DPI ||
> -		    comp_type == MTK_DSI) {
> +		    comp_type == MTK_DP_INTF) {

These were nice and alphabetically ordered, why are you moving MTK_DSI up there?!

  		    comp_type == MTK_DISP_RDMA ||
		    comp_type == MTK_DP_INTF ||
  		    comp_type == MTK_DPI ||
		    comp_type == MTK_DSI) {

... that's how it should look like.

>   			dev_info(dev, "Adding component match for %pOF\n",
>   				 node);
>   			drm_of_component_match_add(dev, &match, component_compare_of,
> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
> index 3e998bfb795a..e4b84c347201 100644
> --- a/include/linux/soc/mediatek/mtk-mmsys.h
> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
>   	DDP_COMPONENT_COLOR0,
>   	DDP_COMPONENT_COLOR1,
>   	DDP_COMPONENT_DITHER,
> -	DDP_COMPONENT_DP_INTF0,
> -	DDP_COMPONENT_DP_INTF1,
>   	DDP_COMPONENT_DPI0,
>   	DDP_COMPONENT_DPI1,
>   	DDP_COMPONENT_DSC0,
>   	DDP_COMPONENT_DSC1,
> +	DDP_COMPONENT_DP_INTF0,
> +	DDP_COMPONENT_DP_INTF1,

Why are you moving this?!

>   	DDP_COMPONENT_DSI0,
>   	DDP_COMPONENT_DSI1,
>   	DDP_COMPONENT_DSI2,



_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-05-25 12:58     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:58 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <jason-jh.lin@mediatek.com>.
> 

Only after finishing the review, I've noticed that I just wrote the same things
that I wrote in my review for version 8... and if I recall correctly, this is not
the first time that something like that happens.

Please pay attention to what reviewers say, as to not waste anyone's time.


> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   
> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;
> @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   
>   	vm.pixelclock = pll_rate / factor;
>   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {

The indentation was perfect before that change...

>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> -	else
> +	} else {
>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> -
> +	}
>   
>   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
>   
> @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
>   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> -	hsync.sync_width = vm.hsync_len;
> -	hsync.back_porch = vm.hback_porch;
> -	hsync.front_porch = vm.hfront_porch;
> +	if (dpi->conf->is_dpintf) {
> +		hsync.sync_width = vm.hsync_len / 4;
> +		hsync.back_porch = vm.hback_porch / 4;
> +		hsync.front_porch = vm.hfront_porch / 4;
> +	} else {
> +		hsync.sync_width = vm.hsync_len;
> +		hsync.back_porch = vm.hback_porch;
> +		hsync.front_porch = vm.hfront_porch;
> +	}

This looks way better:

	hsync.sync_width = vm.hsync_len;
	hsync.back_porch = vm.hback_porch;
	hsync.front_porch = vm.hfront_porch;

	/* For DPINTF, we need to divide everything by 4 .. lanes? */
	if (dpi->conf->is_dpintf) {
		hsync.sync_width /= 4;
		hsync.back_porch /= 4;
		hsync.front_porch /= 4;
	}

>   	hsync.shift_half_line = false;
>   	vsync_lodd.sync_width = vm.vsync_len;
>   	vsync_lodd.back_porch = vm.vback_porch;
> @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   	mtk_dpi_config_channel_limit(dpi);
>   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
>   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> -	mtk_dpi_config_2n_h_fre(dpi);
> -	mtk_dpi_dual_edge(dpi);
> -	mtk_dpi_config_disable_edge(dpi);
> +	if (dpi->conf->is_dpintf) {
> +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> +			     DPINTF_INPUT_2P_EN);
> +	} else {
> +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> +		mtk_dpi_config_2n_h_fre(dpi);
> +		mtk_dpi_dual_edge(dpi);
> +		mtk_dpi_config_disable_edge(dpi);
> +	}
>   	mtk_dpi_sw_reset(dpi, false);
>   
> +	mtk_dpi_enable(dpi);
> +
>   	return 0;
>   }
>   
> @@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>   	u32 *input_fmts;
>   
>   	*num_input_fmts = 0;
> -

Removing this line is not part of adding dpintf support, so don't do that.

>   	input_fmts = kcalloc(1, sizeof(*input_fmts),
>   			     GFP_KERNEL);
>   	if (!input_fmts)
> @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
>   		if (dpi->conf->num_output_fmts)
>   			out_bus_format = dpi->conf->output_fmts[0];
>   
> -	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> -		bridge_state->input_bus_cfg.format,
> -		bridge_state->output_bus_cfg.format);
> +	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> +		 bridge_state->input_bus_cfg.format,
> +		 bridge_state->output_bus_cfg.format);

This message is not giving any constantly changing information, nor any one that
is interesting for the user: keep this as dev_dbg().

>   
>   	dpi->output_fmt = out_bus_format;
>   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
>   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
>   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> +	else
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
>   
>   	return 0;
>   }
> @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
>   {
>   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>   
> -	if (mode->clock > dpi->conf->max_clock_khz)
> +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
>   		return MODE_CLOCK_HIGH;
>   
>   	return MODE_OK;
> @@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
>   		return 2;
>   }
>   
> +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> +{
> +	if (clock < 70000)

is 70000 intentional? Or did you mean 700000?

> +		return 4;
> +	else if (clock < 200000)
> +		return 2;
> +	else
> +		return 1;
> +}
> +
>   static const u32 mt8173_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_1X24,
>   };
> @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_2X12_BE,
>   };
>   
> +static const u32 mt8195_output_fmts[] = {
> +	MEDIA_BUS_FMT_RGB888_1X24,
> +	MEDIA_BUS_FMT_YUV8_1X24,
> +	MEDIA_BUS_FMT_YUYV8_1X16,
> +};
> +
>   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.c_bottom = 0x0010,
>   	.c_top = 0x0FE0,
> @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.y_top = 0x0FE0,
>   };
>   
> +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> +	.c_bottom = 0x0000,
> +	.c_top = 0xFFF,
> +	.y_bottom = 0x0000,
> +	.y_top = 0xFFF,
> +};
> +
>   static const struct mtk_dpi_conf mt8173_conf = {
>   	.cal_factor = mt8173_calculate_factor,
>   	.reg_h_fre_con = 0xe0,
> @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
>   	.limit = &mtk_dpi_limit,
>   };
>   
> +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> +	.cal_factor = mt8195_dpintf_calculate_factor,
> +	.output_fmts = mt8195_output_fmts,
> +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> +	.is_dpintf = true,
> +	.dimension_mask = DPINTF_HPW_MASK,
> +	.hvsize_mask = DPINTF_HSIZE_MASK,
> +	.channel_swap_shift = DPINTF_CH_SWAP,
> +	.yuv422_en_bit = DPINTF_YUV422_EN,
> +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> +	.limit = &mtk_dpintf_limit,
> +};
> +
>   static int mtk_dpi_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>   	if (IS_ERR(dpi->engine_clk)) {
>   		ret = PTR_ERR(dpi->engine_clk);
>   		if (ret != -EPROBE_DEFER)
> -			dev_err(dev, "Failed to get engine clock: %d\n", ret);
> +			dev_err(dev, "Failed to get engine clock: %d\n",
> +				ret);

Why are you breaking this line?

> +
> +		return ret;
> +	}
> +
> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
> +				ret);
> +
> +		return ret;
> +	}
> +

You're getting this clock twice, what happened here?

P.S.: As I explained on the dt-bindings patch, you likely don't even need this
       clock at all.

> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
>   
>   		return ret;
>   	}
> @@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>   	{ .compatible = "mediatek,mt8192-dpi",
>   	  .data = &mt8192_conf,
>   	},
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = &mt8195_dpintf_conf,
> +	},
>   	{ },
>   };
>   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index 3a02fabe1662..dd47dd3f2e4f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -40,10 +40,15 @@
>   #define FAKE_DE_LEVEN			BIT(21)
>   #define FAKE_DE_RODD			BIT(22)
>   #define FAKE_DE_REVEN			BIT(23)
> +#define DPINTF_YUV422_EN		BIT(24)
> +#define DPINTF_CSC_ENABLE		BIT(26)
> +#define DPINTF_INPUT_2P_EN		BIT(29)
>   
>   #define DPI_OUTPUT_SETTING	0x14
>   #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>   #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
>   #define SWAP_RGB			0x00
>   #define SWAP_GBR			0x01
>   #define SWAP_BRG			0x02
> @@ -80,8 +85,10 @@
>   #define DPI_SIZE		0x18
>   #define HSIZE				0
>   #define HSIZE_MASK			(0x1FFF << 0)
> +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
>   #define VSIZE				16
>   #define VSIZE_MASK			(0x1FFF << 16)
> +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
>   
>   #define DPI_DDR_SETTING		0x1C
>   #define DDR_EN				BIT(0)
> @@ -93,24 +100,30 @@
>   #define DPI_TGEN_HWIDTH		0x20
>   #define HPW				0
>   #define HPW_MASK			(0xFFF << 0)
> +#define DPINTF_HPW_MASK			(0xFFFF << 0)
>   
>   #define DPI_TGEN_HPORCH		0x24
>   #define HBP				0
>   #define HBP_MASK			(0xFFF << 0)
> +#define DPINTF_HBP_MASK			(0xFFFF << 0)
>   #define HFP				16
>   #define HFP_MASK			(0xFFF << 16)
> +#define DPINTF_HFP_MASK			(0xFFFF << 16)
>   
>   #define DPI_TGEN_VWIDTH		0x28
>   #define DPI_TGEN_VPORCH		0x2C
>   
>   #define VSYNC_WIDTH_SHIFT		0
>   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
>   #define VSYNC_HALF_LINE_SHIFT		16
>   #define VSYNC_HALF_LINE_MASK		BIT(16)
>   #define VSYNC_BACK_PORCH_SHIFT		0
>   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
>   #define VSYNC_FRONT_PORCH_SHIFT		16
>   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
>   
>   #define DPI_BG_HCNTL		0x30
>   #define BG_RIGHT			(0x1FFF << 0)
> @@ -217,4 +230,26 @@
>   
>   #define EDGE_SEL_EN			BIT(5)
>   #define H_FRE_2N			BIT(25)
> +
> +#define RGB_TO_JPEG			0x00

This is 0x0

> +#define RGB_TO_FULL709			0x01

0x1

> +#define RGB_TO_BT601			0x02

0x2

...remove the unnecessary leading zeros, but... you're not ever
using this set of definitions, so why are you even adding them?

> +#define RGB_TO_BT709			0x03
> +#define JPEG_TO_RGB			0x04
> +#define FULL709_TO_RGB			0x05
> +#define BT601_TO_RGB			0x06
> +#define BT709_TO_RGB			0x07
> +#define JPEG_TO_BT601			0x08
> +#define JPEG_TO_BT709			0x09
> +#define BT601_TO_JPEG			0xA
> +#define BT709_TO_JPEG			0xB
> +#define BT709_TO_BT601			0xC
> +#define BT601_TO_BT709			0xD
> +#define JPEG_TO_CERGB			0x14
> +#define FULL709_TO_CERGB		0x15
> +#define BT601_TO_CERGB			0x16
> +#define BT709_TO_CERGB			0x17
> +#define RGB_TO_CERGB			0x1C
> +#define MATRIX_BIT			BIT(8)
> +#define EXT_MATRIX_EN			BIT(12)
>   #endif /* __MTK_DPI_REGS_H */
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 245d0074e12d..3738665a712e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>   	[MTK_DISP_WDMA] = "wdma",
>   	[MTK_DPI] = "dpi",
>   	[MTK_DSI] = "dsi",
> +	[MTK_DP_INTF] = "dp-intf",
> +	[MTK_DISP_PWM] = "pwm",
> +	[MTK_DISP_MUTEX] = "mutex",
> +	[MTK_DISP_OD] = "od",
> +	[MTK_DISP_BLS] = "bls",

Please keep alphabetic order.

>   };
>   
>   struct mtk_ddp_comp_match {
> @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
>   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
>   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
> +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
> +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },

Indentation issue. Fix it.

>   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
>   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
>   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
> @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>   	    type == MTK_DISP_PWM ||
>   	    type == MTK_DISP_RDMA ||
>   	    type == MTK_DPI ||
> +	    type == MTK_DP_INTF ||
>   	    type == MTK_DSI)
>   		return 0;
>   
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 825d763d2378..c4e683f46a95 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
>   	MTK_DISP_UFOE,
>   	MTK_DISP_WDMA,
>   	MTK_DPI,
> +	MTK_DP_INTF,
>   	MTK_DSI,
>   	MTK_DDP_COMP_TYPE_MAX,
>   };
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index a2a783fc580e..e25ac61aac08 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>   	  .data = (void *)MTK_DPI },
>   	{ .compatible = "mediatek,mt8183-dpi",
>   	  .data = (void *)MTK_DPI },
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = (void *)MTK_DP_INTF },
>   	{ .compatible = "mediatek,mt2701-dsi",
>   	  .data = (void *)MTK_DSI },
>   	{ .compatible = "mediatek,mt8173-dsi",
> @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
>   		    comp_type == MTK_DISP_OVL_2L ||
>   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
>   		    comp_type == MTK_DISP_RDMA ||
> +		    comp_type == MTK_DSI ||
>   		    comp_type == MTK_DPI ||
> -		    comp_type == MTK_DSI) {
> +		    comp_type == MTK_DP_INTF) {

These were nice and alphabetically ordered, why are you moving MTK_DSI up there?!

  		    comp_type == MTK_DISP_RDMA ||
		    comp_type == MTK_DP_INTF ||
  		    comp_type == MTK_DPI ||
		    comp_type == MTK_DSI) {

... that's how it should look like.

>   			dev_info(dev, "Adding component match for %pOF\n",
>   				 node);
>   			drm_of_component_match_add(dev, &match, component_compare_of,
> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
> index 3e998bfb795a..e4b84c347201 100644
> --- a/include/linux/soc/mediatek/mtk-mmsys.h
> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
>   	DDP_COMPONENT_COLOR0,
>   	DDP_COMPONENT_COLOR1,
>   	DDP_COMPONENT_DITHER,
> -	DDP_COMPONENT_DP_INTF0,
> -	DDP_COMPONENT_DP_INTF1,
>   	DDP_COMPONENT_DPI0,
>   	DDP_COMPONENT_DPI1,
>   	DDP_COMPONENT_DSC0,
>   	DDP_COMPONENT_DSC1,
> +	DDP_COMPONENT_DP_INTF0,
> +	DDP_COMPONENT_DP_INTF1,

Why are you moving this?!

>   	DDP_COMPONENT_DSI0,
>   	DDP_COMPONENT_DSI1,
>   	DDP_COMPONENT_DSI2,



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-05-25 12:58     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 12:58 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> 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 <jason-jh.lin@mediatek.com>.
> 

Only after finishing the review, I've noticed that I just wrote the same things
that I wrote in my review for version 8... and if I recall correctly, this is not
the first time that something like that happens.

Please pay attention to what reviewers say, as to not waste anyone's time.


> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   
> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;
> @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   
>   	vm.pixelclock = pll_rate / factor;
>   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {

The indentation was perfect before that change...

>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> -	else
> +	} else {
>   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> -
> +	}
>   
>   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
>   
> @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
>   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
>   			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> -	hsync.sync_width = vm.hsync_len;
> -	hsync.back_porch = vm.hback_porch;
> -	hsync.front_porch = vm.hfront_porch;
> +	if (dpi->conf->is_dpintf) {
> +		hsync.sync_width = vm.hsync_len / 4;
> +		hsync.back_porch = vm.hback_porch / 4;
> +		hsync.front_porch = vm.hfront_porch / 4;
> +	} else {
> +		hsync.sync_width = vm.hsync_len;
> +		hsync.back_porch = vm.hback_porch;
> +		hsync.front_porch = vm.hfront_porch;
> +	}

This looks way better:

	hsync.sync_width = vm.hsync_len;
	hsync.back_porch = vm.hback_porch;
	hsync.front_porch = vm.hfront_porch;

	/* For DPINTF, we need to divide everything by 4 .. lanes? */
	if (dpi->conf->is_dpintf) {
		hsync.sync_width /= 4;
		hsync.back_porch /= 4;
		hsync.front_porch /= 4;
	}

>   	hsync.shift_half_line = false;
>   	vsync_lodd.sync_width = vm.vsync_len;
>   	vsync_lodd.back_porch = vm.vback_porch;
> @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   	mtk_dpi_config_channel_limit(dpi);
>   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
>   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> -	mtk_dpi_config_2n_h_fre(dpi);
> -	mtk_dpi_dual_edge(dpi);
> -	mtk_dpi_config_disable_edge(dpi);
> +	if (dpi->conf->is_dpintf) {
> +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> +			     DPINTF_INPUT_2P_EN);
> +	} else {
> +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> +		mtk_dpi_config_2n_h_fre(dpi);
> +		mtk_dpi_dual_edge(dpi);
> +		mtk_dpi_config_disable_edge(dpi);
> +	}
>   	mtk_dpi_sw_reset(dpi, false);
>   
> +	mtk_dpi_enable(dpi);
> +
>   	return 0;
>   }
>   
> @@ -608,7 +639,6 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>   	u32 *input_fmts;
>   
>   	*num_input_fmts = 0;
> -

Removing this line is not part of adding dpintf support, so don't do that.

>   	input_fmts = kcalloc(1, sizeof(*input_fmts),
>   			     GFP_KERNEL);
>   	if (!input_fmts)
> @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
>   		if (dpi->conf->num_output_fmts)
>   			out_bus_format = dpi->conf->output_fmts[0];
>   
> -	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> -		bridge_state->input_bus_cfg.format,
> -		bridge_state->output_bus_cfg.format);
> +	dev_info(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
> +		 bridge_state->input_bus_cfg.format,
> +		 bridge_state->output_bus_cfg.format);

This message is not giving any constantly changing information, nor any one that
is interesting for the user: keep this as dev_dbg().

>   
>   	dpi->output_fmt = out_bus_format;
>   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
>   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
>   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> +	else
> +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
>   
>   	return 0;
>   }
> @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
>   {
>   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>   
> -	if (mode->clock > dpi->conf->max_clock_khz)
> +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf->max_clock_khz)
>   		return MODE_CLOCK_HIGH;
>   
>   	return MODE_OK;
> @@ -801,6 +834,16 @@ static unsigned int mt8183_calculate_factor(int clock)
>   		return 2;
>   }
>   
> +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> +{
> +	if (clock < 70000)

is 70000 intentional? Or did you mean 700000?

> +		return 4;
> +	else if (clock < 200000)
> +		return 2;
> +	else
> +		return 1;
> +}
> +
>   static const u32 mt8173_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_1X24,
>   };
> @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
>   	MEDIA_BUS_FMT_RGB888_2X12_BE,
>   };
>   
> +static const u32 mt8195_output_fmts[] = {
> +	MEDIA_BUS_FMT_RGB888_1X24,
> +	MEDIA_BUS_FMT_YUV8_1X24,
> +	MEDIA_BUS_FMT_YUYV8_1X16,
> +};
> +
>   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.c_bottom = 0x0010,
>   	.c_top = 0x0FE0,
> @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
>   	.y_top = 0x0FE0,
>   };
>   
> +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> +	.c_bottom = 0x0000,
> +	.c_top = 0xFFF,
> +	.y_bottom = 0x0000,
> +	.y_top = 0xFFF,
> +};
> +
>   static const struct mtk_dpi_conf mt8173_conf = {
>   	.cal_factor = mt8173_calculate_factor,
>   	.reg_h_fre_con = 0xe0,
> @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf = {
>   	.limit = &mtk_dpi_limit,
>   };
>   
> +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> +	.cal_factor = mt8195_dpintf_calculate_factor,
> +	.output_fmts = mt8195_output_fmts,
> +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> +	.is_dpintf = true,
> +	.dimension_mask = DPINTF_HPW_MASK,
> +	.hvsize_mask = DPINTF_HSIZE_MASK,
> +	.channel_swap_shift = DPINTF_CH_SWAP,
> +	.yuv422_en_bit = DPINTF_YUV422_EN,
> +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> +	.limit = &mtk_dpintf_limit,
> +};
> +
>   static int mtk_dpi_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>   	if (IS_ERR(dpi->engine_clk)) {
>   		ret = PTR_ERR(dpi->engine_clk);
>   		if (ret != -EPROBE_DEFER)
> -			dev_err(dev, "Failed to get engine clock: %d\n", ret);
> +			dev_err(dev, "Failed to get engine clock: %d\n",
> +				ret);

Why are you breaking this line?

> +
> +		return ret;
> +	}
> +
> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
> +				ret);
> +
> +		return ret;
> +	}
> +

You're getting this clock twice, what happened here?

P.S.: As I explained on the dt-bindings patch, you likely don't even need this
       clock at all.

> +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> +	if (IS_ERR(dpi->dpi_ck_cg)) {
> +		ret = PTR_ERR(dpi->dpi_ck_cg);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get dpi ck cg clock: %d\n", ret);
>   
>   		return ret;
>   	}
> @@ -1004,6 +1093,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>   	{ .compatible = "mediatek,mt8192-dpi",
>   	  .data = &mt8192_conf,
>   	},
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = &mt8195_dpintf_conf,
> +	},
>   	{ },
>   };
>   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index 3a02fabe1662..dd47dd3f2e4f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -40,10 +40,15 @@
>   #define FAKE_DE_LEVEN			BIT(21)
>   #define FAKE_DE_RODD			BIT(22)
>   #define FAKE_DE_REVEN			BIT(23)
> +#define DPINTF_YUV422_EN		BIT(24)
> +#define DPINTF_CSC_ENABLE		BIT(26)
> +#define DPINTF_INPUT_2P_EN		BIT(29)
>   
>   #define DPI_OUTPUT_SETTING	0x14
>   #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>   #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
>   #define SWAP_RGB			0x00
>   #define SWAP_GBR			0x01
>   #define SWAP_BRG			0x02
> @@ -80,8 +85,10 @@
>   #define DPI_SIZE		0x18
>   #define HSIZE				0
>   #define HSIZE_MASK			(0x1FFF << 0)
> +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
>   #define VSIZE				16
>   #define VSIZE_MASK			(0x1FFF << 16)
> +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
>   
>   #define DPI_DDR_SETTING		0x1C
>   #define DDR_EN				BIT(0)
> @@ -93,24 +100,30 @@
>   #define DPI_TGEN_HWIDTH		0x20
>   #define HPW				0
>   #define HPW_MASK			(0xFFF << 0)
> +#define DPINTF_HPW_MASK			(0xFFFF << 0)
>   
>   #define DPI_TGEN_HPORCH		0x24
>   #define HBP				0
>   #define HBP_MASK			(0xFFF << 0)
> +#define DPINTF_HBP_MASK			(0xFFFF << 0)
>   #define HFP				16
>   #define HFP_MASK			(0xFFF << 16)
> +#define DPINTF_HFP_MASK			(0xFFFF << 16)
>   
>   #define DPI_TGEN_VWIDTH		0x28
>   #define DPI_TGEN_VPORCH		0x2C
>   
>   #define VSYNC_WIDTH_SHIFT		0
>   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
>   #define VSYNC_HALF_LINE_SHIFT		16
>   #define VSYNC_HALF_LINE_MASK		BIT(16)
>   #define VSYNC_BACK_PORCH_SHIFT		0
>   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
>   #define VSYNC_FRONT_PORCH_SHIFT		16
>   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
>   
>   #define DPI_BG_HCNTL		0x30
>   #define BG_RIGHT			(0x1FFF << 0)
> @@ -217,4 +230,26 @@
>   
>   #define EDGE_SEL_EN			BIT(5)
>   #define H_FRE_2N			BIT(25)
> +
> +#define RGB_TO_JPEG			0x00

This is 0x0

> +#define RGB_TO_FULL709			0x01

0x1

> +#define RGB_TO_BT601			0x02

0x2

...remove the unnecessary leading zeros, but... you're not ever
using this set of definitions, so why are you even adding them?

> +#define RGB_TO_BT709			0x03
> +#define JPEG_TO_RGB			0x04
> +#define FULL709_TO_RGB			0x05
> +#define BT601_TO_RGB			0x06
> +#define BT709_TO_RGB			0x07
> +#define JPEG_TO_BT601			0x08
> +#define JPEG_TO_BT709			0x09
> +#define BT601_TO_JPEG			0xA
> +#define BT709_TO_JPEG			0xB
> +#define BT709_TO_BT601			0xC
> +#define BT601_TO_BT709			0xD
> +#define JPEG_TO_CERGB			0x14
> +#define FULL709_TO_CERGB		0x15
> +#define BT601_TO_CERGB			0x16
> +#define BT709_TO_CERGB			0x17
> +#define RGB_TO_CERGB			0x1C
> +#define MATRIX_BIT			BIT(8)
> +#define EXT_MATRIX_EN			BIT(12)
>   #endif /* __MTK_DPI_REGS_H */
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 245d0074e12d..3738665a712e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -419,6 +419,11 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>   	[MTK_DISP_WDMA] = "wdma",
>   	[MTK_DPI] = "dpi",
>   	[MTK_DSI] = "dsi",
> +	[MTK_DP_INTF] = "dp-intf",
> +	[MTK_DISP_PWM] = "pwm",
> +	[MTK_DISP_MUTEX] = "mutex",
> +	[MTK_DISP_OD] = "od",
> +	[MTK_DISP_BLS] = "bls",

Please keep alphabetic order.

>   };
>   
>   struct mtk_ddp_comp_match {
> @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
>   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
>   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
> +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi },
> +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi },

Indentation issue. Fix it.

>   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
>   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
>   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
> @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>   	    type == MTK_DISP_PWM ||
>   	    type == MTK_DISP_RDMA ||
>   	    type == MTK_DPI ||
> +	    type == MTK_DP_INTF ||
>   	    type == MTK_DSI)
>   		return 0;
>   
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 825d763d2378..c4e683f46a95 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
>   	MTK_DISP_UFOE,
>   	MTK_DISP_WDMA,
>   	MTK_DPI,
> +	MTK_DP_INTF,
>   	MTK_DSI,
>   	MTK_DDP_COMP_TYPE_MAX,
>   };
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index a2a783fc580e..e25ac61aac08 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -690,6 +690,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>   	  .data = (void *)MTK_DPI },
>   	{ .compatible = "mediatek,mt8183-dpi",
>   	  .data = (void *)MTK_DPI },
> +	{ .compatible = "mediatek,mt8195-dpintf",
> +	  .data = (void *)MTK_DP_INTF },
>   	{ .compatible = "mediatek,mt2701-dsi",
>   	  .data = (void *)MTK_DSI },
>   	{ .compatible = "mediatek,mt8173-dsi",
> @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
>   		    comp_type == MTK_DISP_OVL_2L ||
>   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
>   		    comp_type == MTK_DISP_RDMA ||
> +		    comp_type == MTK_DSI ||
>   		    comp_type == MTK_DPI ||
> -		    comp_type == MTK_DSI) {
> +		    comp_type == MTK_DP_INTF) {

These were nice and alphabetically ordered, why are you moving MTK_DSI up there?!

  		    comp_type == MTK_DISP_RDMA ||
		    comp_type == MTK_DP_INTF ||
  		    comp_type == MTK_DPI ||
		    comp_type == MTK_DSI) {

... that's how it should look like.

>   			dev_info(dev, "Adding component match for %pOF\n",
>   				 node);
>   			drm_of_component_match_add(dev, &match, component_compare_of,
> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
> index 3e998bfb795a..e4b84c347201 100644
> --- a/include/linux/soc/mediatek/mtk-mmsys.h
> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
>   	DDP_COMPONENT_COLOR0,
>   	DDP_COMPONENT_COLOR1,
>   	DDP_COMPONENT_DITHER,
> -	DDP_COMPONENT_DP_INTF0,
> -	DDP_COMPONENT_DP_INTF1,
>   	DDP_COMPONENT_DPI0,
>   	DDP_COMPONENT_DPI1,
>   	DDP_COMPONENT_DSC0,
>   	DDP_COMPONENT_DSC1,
> +	DDP_COMPONENT_DP_INTF0,
> +	DDP_COMPONENT_DP_INTF1,

Why are you moving this?!

>   	DDP_COMPONENT_DSI0,
>   	DDP_COMPONENT_DSI1,
>   	DDP_COMPONENT_DSI2,



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25 13:04     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 13:04 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> This patch adds External DisplayPort support to the mt8195 eDP driver.
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
>   1 file changed, 81 insertions(+), 23 deletions(-)
> 

Your patch [18/21], contained in this series, introduces mtk_dp.c.
This patch [19/21] cannot be applied cleanly on top of 18/21.

What happened here?!?

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
@ 2022-05-25 13:04     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 13:04 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> This patch adds External DisplayPort support to the mt8195 eDP driver.
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
>   1 file changed, 81 insertions(+), 23 deletions(-)
> 

Your patch [18/21], contained in this series, introduces mtk_dp.c.
This patch [19/21] cannot be applied cleanly on top of 18/21.

What happened here?!?

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
@ 2022-05-25 13:04     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 13:04 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> This patch adds External DisplayPort support to the mt8195 eDP driver.
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
>   1 file changed, 81 insertions(+), 23 deletions(-)
> 

Your patch [18/21], contained in this series, introduces mtk_dp.c.
This patch [19/21] cannot be applied cleanly on top of 18/21.

What happened here?!?

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
@ 2022-05-25 13:04     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 13:04 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> This patch adds External DisplayPort support to the mt8195 eDP driver.
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
>   1 file changed, 81 insertions(+), 23 deletions(-)
> 

Your patch [18/21], contained in this series, introduces mtk_dp.c.
This patch [19/21] cannot be applied cleanly on top of 18/21.

What happened here?!?

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
@ 2022-05-25 13:04     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 13:04 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> This patch adds External DisplayPort support to the mt8195 eDP driver.
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
>   1 file changed, 81 insertions(+), 23 deletions(-)
> 

Your patch [18/21], contained in this series, introduces mtk_dp.c.
This patch [19/21] cannot be applied cleanly on top of 18/21.

What happened here?!?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-25 15:30     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 15:30 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>   1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +

You should add port@0 (and port@1, probably) as required... with what you've done
here, you're saying that "ports" is required, but you're allowing it to be empty..

   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:
       - port@0
       - port@1

^^^ that's how it should look.

> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware

As you've put it (in the example below), the max-linkrate property wants a value
that corresponds to what you find in the HW registers... this is wrong.

Devicetree bindings should be generic and devicetrees shouldn't have hardware
specific bits inside, hence, please change this property to accept a link rate
specified in Mbps and also specify that in the description.

Thanks,
Angelo

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-25 15:30     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 15:30 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>   1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +

You should add port@0 (and port@1, probably) as required... with what you've done
here, you're saying that "ports" is required, but you're allowing it to be empty..

   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:
       - port@0
       - port@1

^^^ that's how it should look.

> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware

As you've put it (in the example below), the max-linkrate property wants a value
that corresponds to what you find in the HW registers... this is wrong.

Devicetree bindings should be generic and devicetrees shouldn't have hardware
specific bits inside, hence, please change this property to accept a link rate
specified in Mbps and also specify that in the description.

Thanks,
Angelo

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-25 15:30     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 15:30 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>   1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +

You should add port@0 (and port@1, probably) as required... with what you've done
here, you're saying that "ports" is required, but you're allowing it to be empty..

   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:
       - port@0
       - port@1

^^^ that's how it should look.

> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware

As you've put it (in the example below), the max-linkrate property wants a value
that corresponds to what you find in the HW registers... this is wrong.

Devicetree bindings should be generic and devicetrees shouldn't have hardware
specific bits inside, hence, please change this property to accept a link rate
specified in Mbps and also specify that in the description.

Thanks,
Angelo

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-25 15:30     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 15:30 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>   1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +

You should add port@0 (and port@1, probably) as required... with what you've done
here, you're saying that "ports" is required, but you're allowing it to be empty..

   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:
       - port@0
       - port@1

^^^ that's how it should look.

> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware

As you've put it (in the example below), the max-linkrate property wants a value
that corresponds to what you find in the HW registers... this is wrong.

Devicetree bindings should be generic and devicetrees shouldn't have hardware
specific bits inside, hence, please change this property to accept a link rate
specified in Mbps and also specify that in the description.

Thanks,
Angelo

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-05-25 15:30     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 450+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-25 15:30 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>   .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>   1 file changed, 99 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 000000000000..36ae0a6df299
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -0,0 +1,99 @@
> +# 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 <ck.hu@mediatek.com>
> +  - Jitao shi <jitao.shi@mediatek.com>
> +
> +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
> +

You should add port@0 (and port@1, probably) as required... with what you've done
here, you're saying that "ports" is required, but you're allowing it to be empty..

   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:
       - port@0
       - port@1

^^^ that's how it should look.

> +  max-lanes:
> +    maxItems: 1
> +    description: maximum number of lanes supported by the hardware
> +
> +  max-linkrate:
> +    maxItems: 1
> +    description: maximum link rate supported by the hardware

As you've put it (in the example below), the max-linkrate property wants a value
that corresponds to what you find in the HW registers... this is wrong.

Devicetree bindings should be generic and devicetrees shouldn't have hardware
specific bits inside, hence, please change this property to accept a link rate
specified in Mbps and also specify that in the description.

Thanks,
Angelo

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - ports
> +  - max-lanes
> +  - max-linkrate
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +    edp_tx: edp_tx@1c500000 {
> +        compatible = "mediatek,mt8195-dp-tx";
> +        reg = <0 0x1c500000 0 0x8000>;
> +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&edp_pin>;
> +        max-lanes = /bits/ 8 <4>;
> +        max-linkrate = /bits/ 8 <0x1e>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +                edp_in: endpoint {
> +                    remote-endpoint = <&dp_intf0_out>;
> +                };
> +            };
> +            port@1 {
> +                reg = <1>;
> +                edp_out: endpoint {
> +                	remote-endpoint = <&panel_in>;
> +                };
> +            };
> +        };
> +    };

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-30  7:44     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:44 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without CK/DE pol support

It seems that DP_INTF has no CK/DE pol function. If so, could you
explain why DP_INTF has this difference with DPI?

Regards,
CK

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 4746eb342567..545a1337cc89 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
>  	bool edge_sel_en;
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
> +	bool is_ck_de_pol;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> *dpi,
>  			       struct mtk_dpi_polarities *dpi_pol)
>  {
>  	unsigned int pol;
> +	unsigned int mask;
>  
> -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> |
> -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> |
> -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
> +	mask = HSYNC_POL | VSYNC_POL;
> +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
>  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> VSYNC_POL);
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> +	if (dpi->conf->is_ck_de_pol) {
> +		mask |= CK_POL | DE_POL;
> +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : CK_POL) |
> +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : DE_POL);
> +	}
> +
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
>  }
>  
>  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.max_clock_khz = 300000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.max_clock_khz = 100000,
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-05-30  7:44     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:44 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without CK/DE pol support

It seems that DP_INTF has no CK/DE pol function. If so, could you
explain why DP_INTF has this difference with DPI?

Regards,
CK

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 4746eb342567..545a1337cc89 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
>  	bool edge_sel_en;
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
> +	bool is_ck_de_pol;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> *dpi,
>  			       struct mtk_dpi_polarities *dpi_pol)
>  {
>  	unsigned int pol;
> +	unsigned int mask;
>  
> -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> |
> -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> |
> -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
> +	mask = HSYNC_POL | VSYNC_POL;
> +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
>  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> VSYNC_POL);
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> +	if (dpi->conf->is_ck_de_pol) {
> +		mask |= CK_POL | DE_POL;
> +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : CK_POL) |
> +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : DE_POL);
> +	}
> +
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
>  }
>  
>  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.max_clock_khz = 300000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.max_clock_khz = 100000,
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-05-30  7:44     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:44 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without CK/DE pol support

It seems that DP_INTF has no CK/DE pol function. If so, could you
explain why DP_INTF has this difference with DPI?

Regards,
CK

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 4746eb342567..545a1337cc89 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
>  	bool edge_sel_en;
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
> +	bool is_ck_de_pol;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> *dpi,
>  			       struct mtk_dpi_polarities *dpi_pol)
>  {
>  	unsigned int pol;
> +	unsigned int mask;
>  
> -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> |
> -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> |
> -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
> +	mask = HSYNC_POL | VSYNC_POL;
> +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
>  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> VSYNC_POL);
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> +	if (dpi->conf->is_ck_de_pol) {
> +		mask |= CK_POL | DE_POL;
> +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : CK_POL) |
> +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : DE_POL);
> +	}
> +
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
>  }
>  
>  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.max_clock_khz = 300000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.max_clock_khz = 100000,
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-05-30  7:44     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:44 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without CK/DE pol support

It seems that DP_INTF has no CK/DE pol function. If so, could you
explain why DP_INTF has this difference with DPI?

Regards,
CK

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 4746eb342567..545a1337cc89 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
>  	bool edge_sel_en;
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
> +	bool is_ck_de_pol;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> *dpi,
>  			       struct mtk_dpi_polarities *dpi_pol)
>  {
>  	unsigned int pol;
> +	unsigned int mask;
>  
> -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> |
> -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> |
> -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
> +	mask = HSYNC_POL | VSYNC_POL;
> +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
>  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> VSYNC_POL);
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> +	if (dpi->conf->is_ck_de_pol) {
> +		mask |= CK_POL | DE_POL;
> +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : CK_POL) |
> +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : DE_POL);
> +	}
> +
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
>  }
>  
>  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.max_clock_khz = 300000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.max_clock_khz = 100000,
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-05-30  7:44     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:44 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without CK/DE pol support

It seems that DP_INTF has no CK/DE pol function. If so, could you
explain why DP_INTF has this difference with DPI?

Regards,
CK

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 4746eb342567..545a1337cc89 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
>  	bool edge_sel_en;
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
> +	bool is_ck_de_pol;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> *dpi,
>  			       struct mtk_dpi_polarities *dpi_pol)
>  {
>  	unsigned int pol;
> +	unsigned int mask;
>  
> -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> |
> -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> |
> -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
> +	mask = HSYNC_POL | VSYNC_POL;
> +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> HSYNC_POL) |
>  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> VSYNC_POL);
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> +	if (dpi->conf->is_ck_de_pol) {
> +		mask |= CK_POL | DE_POL;
> +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : CK_POL) |
> +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> +			0 : DE_POL);
> +	}
> +
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
>  }
>  
>  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.max_clock_khz = 300000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.max_clock_khz = 100000,
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.max_clock_khz = 150000,
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> +	.is_ck_de_pol = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-30  7:50     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:


On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without swap_input support
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 545a1337cc89..454f8563efae 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
> +	bool swap_input_support;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct
> mtk_dpi *dpi,
>  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_BGR);
>  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
>  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, true);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, true);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, true);

As [1], please keep in touch with Mediatek engineer.

Regards,
CK

[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/

>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	} else {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, false);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	}
>  }
> @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-05-30  7:50     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Hi, Guillaume:


On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without swap_input support
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 545a1337cc89..454f8563efae 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
> +	bool swap_input_support;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct
> mtk_dpi *dpi,
>  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_BGR);
>  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
>  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, true);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, true);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, true);

As [1], please keep in touch with Mediatek engineer.

Regards,
CK

[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/

>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	} else {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, false);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	}
>  }
> @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-05-30  7:50     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:


On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without swap_input support
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 545a1337cc89..454f8563efae 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
> +	bool swap_input_support;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct
> mtk_dpi *dpi,
>  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_BGR);
>  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
>  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, true);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, true);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, true);

As [1], please keep in touch with Mediatek engineer.

Regards,
CK

[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/

>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	} else {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, false);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	}
>  }
> @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-05-30  7:50     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:


On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without swap_input support
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 545a1337cc89..454f8563efae 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
> +	bool swap_input_support;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct
> mtk_dpi *dpi,
>  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_BGR);
>  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
>  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, true);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, true);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, true);

As [1], please keep in touch with Mediatek engineer.

Regards,
CK

[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/

>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	} else {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, false);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	}
>  }
> @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-05-30  7:50     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:


On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Adds a bit of flexibility to support SoCs without swap_input support
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 545a1337cc89..454f8563efae 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
> +	bool swap_input_support;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct
> mtk_dpi *dpi,
>  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_BGR);
>  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
>  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
>  		mtk_dpi_config_yuv422_enable(dpi, true);
>  		mtk_dpi_config_csc_enable(dpi, true);
> -		mtk_dpi_config_swap_input(dpi, true);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, true);

As [1], please keep in touch with Mediatek engineer.

Regards,
CK

[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/

>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	} else {
>  		mtk_dpi_config_yuv422_enable(dpi, false);
>  		mtk_dpi_config_csc_enable(dpi, false);
> -		mtk_dpi_config_swap_input(dpi, false);
> +		if (dpi->conf->swap_input_support)
> +			mtk_dpi_config_swap_input(dpi, false);
>  		mtk_dpi_config_channel_swap(dpi,
> MTK_DPI_OUT_CHANNEL_SWAP_RGB);
>  	}
>  }
> @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.output_fmts = mt8183_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.output_fmts = mt8173_output_fmts,
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
> +	.swap_input_support = true,
>  	.limit = &mtk_dpi_limit,
>  };
>  


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-30  7:55     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the dimension mask to the SoC config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
>  1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 454f8563efae..bf098f36a466 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -127,6 +127,8 @@ struct mtk_dpi_conf {
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
>  	bool swap_input_support;
> +	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
> +	u32 dimension_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
> @@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
@ 2022-05-30  7:55     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the dimension mask to the SoC config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
>  1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 454f8563efae..bf098f36a466 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -127,6 +127,8 @@ struct mtk_dpi_conf {
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
>  	bool swap_input_support;
> +	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
> +	u32 dimension_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
> @@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
@ 2022-05-30  7:55     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the dimension mask to the SoC config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
>  1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 454f8563efae..bf098f36a466 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -127,6 +127,8 @@ struct mtk_dpi_conf {
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
>  	bool swap_input_support;
> +	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
> +	u32 dimension_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
> @@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
@ 2022-05-30  7:55     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the dimension mask to the SoC config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
>  1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 454f8563efae..bf098f36a466 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -127,6 +127,8 @@ struct mtk_dpi_conf {
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
>  	bool swap_input_support;
> +	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
> +	u32 dimension_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
> @@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
@ 2022-05-30  7:55     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  7:55 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the dimension mask to the SoC config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 26 ++++++++++++++++----------
>  1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 454f8563efae..bf098f36a466 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -127,6 +127,8 @@ struct mtk_dpi_conf {
>  	u32 num_output_fmts;
>  	bool is_ck_de_pol;
>  	bool swap_input_support;
> +	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
> +	u32 dimension_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -156,30 +158,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_config_vsync_lodd(struct mtk_dpi *dpi,
> @@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
> +	.dimension_mask = HPW_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-30  8:21     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:21 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the hvsize mask to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index bf098f36a466..6eeda222a973 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -129,6 +129,8 @@ struct mtk_dpi_conf {
>  	bool swap_input_support;
>  	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
>  	u32 dimension_mask;
> +	/* HSIZE and VSIZE mask (no shift) */
> +	u32 hvsize_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct
> mtk_dpi *dpi, bool inter)
>  
>  static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width,
> u32 height)
>  {
> -	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> -	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> +	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
> +		     dpi->conf->hvsize_mask << HSIZE);
> +	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
> +		     dpi->conf->hvsize_mask << VSIZE);
>  }
>  
>  static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
> @@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
@ 2022-05-30  8:21     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:21 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the hvsize mask to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index bf098f36a466..6eeda222a973 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -129,6 +129,8 @@ struct mtk_dpi_conf {
>  	bool swap_input_support;
>  	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
>  	u32 dimension_mask;
> +	/* HSIZE and VSIZE mask (no shift) */
> +	u32 hvsize_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct
> mtk_dpi *dpi, bool inter)
>  
>  static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width,
> u32 height)
>  {
> -	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> -	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> +	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
> +		     dpi->conf->hvsize_mask << HSIZE);
> +	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
> +		     dpi->conf->hvsize_mask << VSIZE);
>  }
>  
>  static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
> @@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
@ 2022-05-30  8:21     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:21 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the hvsize mask to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index bf098f36a466..6eeda222a973 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -129,6 +129,8 @@ struct mtk_dpi_conf {
>  	bool swap_input_support;
>  	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
>  	u32 dimension_mask;
> +	/* HSIZE and VSIZE mask (no shift) */
> +	u32 hvsize_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct
> mtk_dpi *dpi, bool inter)
>  
>  static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width,
> u32 height)
>  {
> -	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> -	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> +	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
> +		     dpi->conf->hvsize_mask << HSIZE);
> +	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
> +		     dpi->conf->hvsize_mask << VSIZE);
>  }
>  
>  static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
> @@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
@ 2022-05-30  8:21     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:21 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the hvsize mask to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index bf098f36a466..6eeda222a973 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -129,6 +129,8 @@ struct mtk_dpi_conf {
>  	bool swap_input_support;
>  	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
>  	u32 dimension_mask;
> +	/* HSIZE and VSIZE mask (no shift) */
> +	u32 hvsize_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct
> mtk_dpi *dpi, bool inter)
>  
>  static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width,
> u32 height)
>  {
> -	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> -	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> +	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
> +		     dpi->conf->hvsize_mask << HSIZE);
> +	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
> +		     dpi->conf->hvsize_mask << VSIZE);
>  }
>  
>  static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
> @@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
@ 2022-05-30  8:21     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:21 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the hvsize mask to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index bf098f36a466..6eeda222a973 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -129,6 +129,8 @@ struct mtk_dpi_conf {
>  	bool swap_input_support;
>  	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> (no shift) */
>  	u32 dimension_mask;
> +	/* HSIZE and VSIZE mask (no shift) */
> +	u32 hvsize_mask;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct
> mtk_dpi *dpi, bool inter)
>  
>  static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width,
> u32 height)
>  {
> -	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
> -	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> +	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
> +		     dpi->conf->hvsize_mask << HSIZE);
> +	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
> +		     dpi->conf->hvsize_mask << VSIZE);
>  }
>  
>  static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
> @@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.is_ck_de_pol = true,
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
> +	.hvsize_mask = HSIZE_MASK,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-30  8:38     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:38 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Rex-BC Chen, AngeloGioacchino Del Regno, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the swap shift value to SoC specific config
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6eeda222a973..6d4d8c6ec47d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
>  	u32 dimension_mask;
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
> +	u32 channel_swap_shift;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  		break;
>  	}
>  
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> CH_SWAP_MASK);
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> >channel_swap_shift,
> +		     CH_SWAP_MASK);

From the definiton:

 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)

This statement should be:

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
>channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);

dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for others.
And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,

Regards,
CK


>  }
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-05-30  8:38     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:38 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the swap shift value to SoC specific config
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6eeda222a973..6d4d8c6ec47d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
>  	u32 dimension_mask;
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
> +	u32 channel_swap_shift;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  		break;
>  	}
>  
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> CH_SWAP_MASK);
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> >channel_swap_shift,
> +		     CH_SWAP_MASK);

From the definiton:

 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)

This statement should be:

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
>channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);

dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for others.
And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,

Regards,
CK


>  }
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-05-30  8:38     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:38 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Rex-BC Chen, AngeloGioacchino Del Regno, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the swap shift value to SoC specific config
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6eeda222a973..6d4d8c6ec47d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
>  	u32 dimension_mask;
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
> +	u32 channel_swap_shift;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  		break;
>  	}
>  
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> CH_SWAP_MASK);
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> >channel_swap_shift,
> +		     CH_SWAP_MASK);

From the definiton:

 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)

This statement should be:

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
>channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);

dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for others.
And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,

Regards,
CK


>  }
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-05-30  8:38     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:38 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Rex-BC Chen, AngeloGioacchino Del Regno, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the swap shift value to SoC specific config
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6eeda222a973..6d4d8c6ec47d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
>  	u32 dimension_mask;
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
> +	u32 channel_swap_shift;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  		break;
>  	}
>  
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> CH_SWAP_MASK);
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> >channel_swap_shift,
> +		     CH_SWAP_MASK);

From the definiton:

 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)

This statement should be:

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
>channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);

dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for others.
And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,

Regards,
CK


>  }
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-05-30  8:38     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:38 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Rex-BC Chen, AngeloGioacchino Del Regno, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the swap shift value to SoC specific config
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6eeda222a973..6d4d8c6ec47d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
>  	u32 dimension_mask;
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
> +	u32 channel_swap_shift;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  		break;
>  	}
>  
> -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> CH_SWAP_MASK);
> +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> >channel_swap_shift,
> +		     CH_SWAP_MASK);

From the definiton:

 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)

This statement should be:

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
>channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);

dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for others.
And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,

Regards,
CK


>  }
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.swap_input_support = true,
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
> +	.channel_swap_shift = CH_SWAP,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-30  8:47     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the yuv422 en bit to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6d4d8c6ec47d..40254cd9d168 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -132,6 +132,7 @@ struct mtk_dpi_conf {
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
>  	u32 channel_swap_shift;
> +	u32 yuv422_en_bit;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
>  {
> -	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
> +	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit :
> 0,
> +		     dpi->conf->yuv422_en_bit);
>  }
>  
>  static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
@ 2022-05-30  8:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the yuv422 en bit to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6d4d8c6ec47d..40254cd9d168 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -132,6 +132,7 @@ struct mtk_dpi_conf {
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
>  	u32 channel_swap_shift;
> +	u32 yuv422_en_bit;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
>  {
> -	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
> +	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit :
> 0,
> +		     dpi->conf->yuv422_en_bit);
>  }
>  
>  static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
@ 2022-05-30  8:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-phy,
	linux-mediatek, Rex-BC Chen, linux-arm-kernel,
	AngeloGioacchino Del Regno

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the yuv422 en bit to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6d4d8c6ec47d..40254cd9d168 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -132,6 +132,7 @@ struct mtk_dpi_conf {
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
>  	u32 channel_swap_shift;
> +	u32 yuv422_en_bit;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
>  {
> -	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
> +	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit :
> 0,
> +		     dpi->conf->yuv422_en_bit);
>  }
>  
>  static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
@ 2022-05-30  8:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the yuv422 en bit to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6d4d8c6ec47d..40254cd9d168 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -132,6 +132,7 @@ struct mtk_dpi_conf {
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
>  	u32 channel_swap_shift;
> +	u32 yuv422_en_bit;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
>  {
> -	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
> +	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit :
> 0,
> +		     dpi->conf->yuv422_en_bit);
>  }
>  
>  static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
@ 2022-05-30  8:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  8:47 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, Rex-BC Chen, dri-devel,
	linux-mediatek, devicetree, linux-kernel, linux-arm-kernel,
	linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> Add flexibility by moving the yuv422 en bit to SoC specific config

Reviewed-by: CK Hu <ck.hu@mediatek.com>

> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 6d4d8c6ec47d..40254cd9d168 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -132,6 +132,7 @@ struct mtk_dpi_conf {
>  	/* HSIZE and VSIZE mask (no shift) */
>  	u32 hvsize_mask;
>  	u32 channel_swap_shift;
> +	u32 yuv422_en_bit;
>  	const struct mtk_dpi_yc_limit *limit;
>  };
>  
> @@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct
> mtk_dpi *dpi,
>  
>  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> enable)
>  {
> -	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
> +	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit :
> 0,
> +		     dpi->conf->yuv422_en_bit);
>  }
>  
>  static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool
> enable)
> @@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  
> @@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
>  	.dimension_mask = HPW_MASK,
>  	.hvsize_mask = HSIZE_MASK,
>  	.channel_swap_shift = CH_SWAP,
> +	.yuv422_en_bit = YUV422_EN,
>  	.limit = &mtk_dpi_limit,
>  };
>  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-30  9:34     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  9:34 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

[snip]

> +
> +static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
> +				    u8
> link_status[DP_LINK_STATUS_SIZE])
> +{
> +	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
> +			 DP_LINK_STATUS_SIZE);
> +}
> +
> +static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
> +			      u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	ret = mtk_dp_training_set_scramble(mtk_dp, false);
> +	if (ret)
> +		return ret;
> +
> +	if (*status_control == 0) {
> +		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
> +		if (ret)
> +			return ret;
> +
> +		val = DP_LINK_SCRAMBLING_DISABLE |
> +			DP_TRAINING_PATTERN_1;
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_1);
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 1;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
> +					       mtk_dp->rx_cap);
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

> +
> +	if (drm_dp_clock_recovery_ok(link_status,
> +				     target_lane_count)) {
> +		mtk_dp->train_info.cr_done = true;
> +		*iteration_count = 1;
> +		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
> +		return 0;
> +	} else if (*prev_lane_adjust == link_status[4]) {
> +		(*iteration_count)++;
> +		if (*prev_lane_adjust &
> DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
> +			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
> +			return -EINVAL;
> +		}
> +	} else {
> +		*prev_lane_adjust = link_status[4];
> +	}
> +	return -EAGAIN;
> +}
> +
> +static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8
> target_linkrate,
> +				u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	if (*status_control == 1) {
> +		if (mtk_dp->train_info.tps4) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_TRAINING_PATTERN_4;
> +		} else if (mtk_dp->train_info.tps3) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_3;
> +		} else {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_2;
> +		}
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				val);
> +
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 2;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
> +					   mtk_dp->rx_cap);
> +
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

Regards,
CK

> +
> +	if (!drm_dp_clock_recovery_ok(link_status,
> +				      target_lane_count)) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
> +		return -EINVAL;
> +	}
> +
> +	if (drm_dp_channel_eq_ok(link_status,
> +				 target_lane_count)) {
> +		mtk_dp->train_info.eq_done = true;
> +		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
> +		return 0;
> +	}
> +
> +	if (*prev_lane_adjust == link_status[4])
> +		(*iteration_count)++;
> +	else
> +		*prev_lane_adjust = link_status[4];
> +
> +	return -EAGAIN;
> +}
> +
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-30  9:34     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  9:34 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

[snip]

> +
> +static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
> +				    u8
> link_status[DP_LINK_STATUS_SIZE])
> +{
> +	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
> +			 DP_LINK_STATUS_SIZE);
> +}
> +
> +static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
> +			      u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	ret = mtk_dp_training_set_scramble(mtk_dp, false);
> +	if (ret)
> +		return ret;
> +
> +	if (*status_control == 0) {
> +		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
> +		if (ret)
> +			return ret;
> +
> +		val = DP_LINK_SCRAMBLING_DISABLE |
> +			DP_TRAINING_PATTERN_1;
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_1);
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 1;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
> +					       mtk_dp->rx_cap);
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

> +
> +	if (drm_dp_clock_recovery_ok(link_status,
> +				     target_lane_count)) {
> +		mtk_dp->train_info.cr_done = true;
> +		*iteration_count = 1;
> +		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
> +		return 0;
> +	} else if (*prev_lane_adjust == link_status[4]) {
> +		(*iteration_count)++;
> +		if (*prev_lane_adjust &
> DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
> +			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
> +			return -EINVAL;
> +		}
> +	} else {
> +		*prev_lane_adjust = link_status[4];
> +	}
> +	return -EAGAIN;
> +}
> +
> +static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8
> target_linkrate,
> +				u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	if (*status_control == 1) {
> +		if (mtk_dp->train_info.tps4) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_TRAINING_PATTERN_4;
> +		} else if (mtk_dp->train_info.tps3) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_3;
> +		} else {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_2;
> +		}
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				val);
> +
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 2;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
> +					   mtk_dp->rx_cap);
> +
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

Regards,
CK

> +
> +	if (!drm_dp_clock_recovery_ok(link_status,
> +				      target_lane_count)) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
> +		return -EINVAL;
> +	}
> +
> +	if (drm_dp_channel_eq_ok(link_status,
> +				 target_lane_count)) {
> +		mtk_dp->train_info.eq_done = true;
> +		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
> +		return 0;
> +	}
> +
> +	if (*prev_lane_adjust == link_status[4])
> +		(*iteration_count)++;
> +	else
> +		*prev_lane_adjust = link_status[4];
> +
> +	return -EAGAIN;
> +}
> +
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-30  9:34     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  9:34 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

[snip]

> +
> +static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
> +				    u8
> link_status[DP_LINK_STATUS_SIZE])
> +{
> +	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
> +			 DP_LINK_STATUS_SIZE);
> +}
> +
> +static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
> +			      u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	ret = mtk_dp_training_set_scramble(mtk_dp, false);
> +	if (ret)
> +		return ret;
> +
> +	if (*status_control == 0) {
> +		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
> +		if (ret)
> +			return ret;
> +
> +		val = DP_LINK_SCRAMBLING_DISABLE |
> +			DP_TRAINING_PATTERN_1;
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_1);
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 1;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
> +					       mtk_dp->rx_cap);
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

> +
> +	if (drm_dp_clock_recovery_ok(link_status,
> +				     target_lane_count)) {
> +		mtk_dp->train_info.cr_done = true;
> +		*iteration_count = 1;
> +		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
> +		return 0;
> +	} else if (*prev_lane_adjust == link_status[4]) {
> +		(*iteration_count)++;
> +		if (*prev_lane_adjust &
> DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
> +			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
> +			return -EINVAL;
> +		}
> +	} else {
> +		*prev_lane_adjust = link_status[4];
> +	}
> +	return -EAGAIN;
> +}
> +
> +static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8
> target_linkrate,
> +				u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	if (*status_control == 1) {
> +		if (mtk_dp->train_info.tps4) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_TRAINING_PATTERN_4;
> +		} else if (mtk_dp->train_info.tps3) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_3;
> +		} else {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_2;
> +		}
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				val);
> +
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 2;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
> +					   mtk_dp->rx_cap);
> +
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

Regards,
CK

> +
> +	if (!drm_dp_clock_recovery_ok(link_status,
> +				      target_lane_count)) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
> +		return -EINVAL;
> +	}
> +
> +	if (drm_dp_channel_eq_ok(link_status,
> +				 target_lane_count)) {
> +		mtk_dp->train_info.eq_done = true;
> +		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
> +		return 0;
> +	}
> +
> +	if (*prev_lane_adjust == link_status[4])
> +		(*iteration_count)++;
> +	else
> +		*prev_lane_adjust = link_status[4];
> +
> +	return -EAGAIN;
> +}
> +
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-30  9:34     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  9:34 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

[snip]

> +
> +static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
> +				    u8
> link_status[DP_LINK_STATUS_SIZE])
> +{
> +	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
> +			 DP_LINK_STATUS_SIZE);
> +}
> +
> +static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
> +			      u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	ret = mtk_dp_training_set_scramble(mtk_dp, false);
> +	if (ret)
> +		return ret;
> +
> +	if (*status_control == 0) {
> +		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
> +		if (ret)
> +			return ret;
> +
> +		val = DP_LINK_SCRAMBLING_DISABLE |
> +			DP_TRAINING_PATTERN_1;
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_1);
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 1;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
> +					       mtk_dp->rx_cap);
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

> +
> +	if (drm_dp_clock_recovery_ok(link_status,
> +				     target_lane_count)) {
> +		mtk_dp->train_info.cr_done = true;
> +		*iteration_count = 1;
> +		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
> +		return 0;
> +	} else if (*prev_lane_adjust == link_status[4]) {
> +		(*iteration_count)++;
> +		if (*prev_lane_adjust &
> DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
> +			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
> +			return -EINVAL;
> +		}
> +	} else {
> +		*prev_lane_adjust = link_status[4];
> +	}
> +	return -EAGAIN;
> +}
> +
> +static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8
> target_linkrate,
> +				u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	if (*status_control == 1) {
> +		if (mtk_dp->train_info.tps4) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_TRAINING_PATTERN_4;
> +		} else if (mtk_dp->train_info.tps3) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_3;
> +		} else {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_2;
> +		}
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				val);
> +
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 2;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
> +					   mtk_dp->rx_cap);
> +
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

Regards,
CK

> +
> +	if (!drm_dp_clock_recovery_ok(link_status,
> +				      target_lane_count)) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
> +		return -EINVAL;
> +	}
> +
> +	if (drm_dp_channel_eq_ok(link_status,
> +				 target_lane_count)) {
> +		mtk_dp->train_info.eq_done = true;
> +		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
> +		return 0;
> +	}
> +
> +	if (*prev_lane_adjust == link_status[4])
> +		(*iteration_count)++;
> +	else
> +		*prev_lane_adjust = link_status[4];
> +
> +	return -EAGAIN;
> +}
> +
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-30  9:34     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30  9:34 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> 

[snip]

> +
> +static void mtk_dp_read_link_status(struct mtk_dp *mtk_dp,
> +				    u8
> link_status[DP_LINK_STATUS_SIZE])
> +{
> +	drm_dp_dpcd_read(&mtk_dp->aux, DP_LANE0_1_STATUS, link_status,
> +			 DP_LINK_STATUS_SIZE);
> +}
> +
> +static int mtk_dp_train_tps_1(struct mtk_dp *mtk_dp,
> +			      u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	ret = mtk_dp_training_set_scramble(mtk_dp, false);
> +	if (ret)
> +		return ret;
> +
> +	if (*status_control == 0) {
> +		ret = mtk_dp_train_set_pattern(mtk_dp, 1);
> +		if (ret)
> +			return ret;
> +
> +		val = DP_LINK_SCRAMBLING_DISABLE |
> +			DP_TRAINING_PATTERN_1;
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_1);
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 1;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux,
> +					       mtk_dp->rx_cap);
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

> +
> +	if (drm_dp_clock_recovery_ok(link_status,
> +				     target_lane_count)) {
> +		mtk_dp->train_info.cr_done = true;
> +		*iteration_count = 1;
> +		dev_dbg(mtk_dp->dev, "Link train CR pass\n");
> +		return 0;
> +	} else if (*prev_lane_adjust == link_status[4]) {
> +		(*iteration_count)++;
> +		if (*prev_lane_adjust &
> DP_ADJUST_VOLTAGE_SWING_LANE0_MASK) {
> +			dev_dbg(mtk_dp->dev, "Link train CQ fail\n");
> +			return -EINVAL;
> +		}
> +	} else {
> +		*prev_lane_adjust = link_status[4];
> +	}
> +	return -EAGAIN;
> +}
> +
> +static int mtk_dp_train_tps_2_3(struct mtk_dp *mtk_dp, u8
> target_linkrate,
> +				u8 target_lane_count, int
> *iteration_count, u8 *lane_adjust,  int *status_control, u8
> *prev_lane_adjust)
> +{
> +	int ret;
> +	u8 val;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +
> +	if (*status_control == 1) {
> +		if (mtk_dp->train_info.tps4) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 4);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_TRAINING_PATTERN_4;
> +		} else if (mtk_dp->train_info.tps3) {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 3);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_3;
> +		} else {
> +			ret = mtk_dp_train_set_pattern(mtk_dp, 2);
> +			if (ret)
> +				return -EINVAL;
> +
> +			val = DP_LINK_SCRAMBLING_DISABLE |
> +				DP_TRAINING_PATTERN_2;
> +		}
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> +				   DP_TRAINING_PATTERN_SET,
> +				val);
> +
> +		drm_dp_dpcd_read(&mtk_dp->aux,
> +				 DP_ADJUST_REQUEST_LANE0_1,
> +				lane_adjust,
> +				sizeof(*lane_adjust) * 2);
> +
> +		mtk_dp_train_update_swing_pre(mtk_dp,
> +					      target_lane_count,
> lane_adjust);
> +		*status_control = 2;
> +		(*iteration_count)++;
> +	}
> +
> +	drm_dp_link_train_channel_eq_delay(&mtk_dp->aux,
> +					   mtk_dp->rx_cap);
> +
> +	mtk_dp_read_link_status(mtk_dp, link_status);

drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status);

Regards,
CK

> +
> +	if (!drm_dp_clock_recovery_ok(link_status,
> +				      target_lane_count)) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +		dev_dbg(mtk_dp->dev, "Link train EQ fail\n");
> +		return -EINVAL;
> +	}
> +
> +	if (drm_dp_channel_eq_ok(link_status,
> +				 target_lane_count)) {
> +		mtk_dp->train_info.eq_done = true;
> +		dev_dbg(mtk_dp->dev, "Link train EQ pass\n");
> +		return 0;
> +	}
> +
> +	if (*prev_lane_adjust == link_status[4])
> +		(*iteration_count)++;
> +	else
> +		*prev_lane_adjust = link_status[4];
> +
> +	return -EAGAIN;
> +}
> +
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-05-30 10:08     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30 10:08 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool connected;
> +	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
> +	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	train_info->irq_status |= hwirq_status | swirq_status;

You mix software control variable and irq status here. Break each flag
in irq_status to variables in train_info to decouple software control
variable and irq status.

> +
> +	if (!train_info->irq_status)
> +		return IRQ_HANDLED;
> +
> +	connected = mtk_dp_plug_state(mtk_dp);
> +	if (connected || !train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +	else if (!connected || train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;
> +
> +	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +		train_info->cable_plugged_in = true;
> +	} else {
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +		train_info->cable_plugged_in = false;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +	}
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-30 10:08     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30 10:08 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool connected;
> +	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
> +	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	train_info->irq_status |= hwirq_status | swirq_status;

You mix software control variable and irq status here. Break each flag
in irq_status to variables in train_info to decouple software control
variable and irq status.

> +
> +	if (!train_info->irq_status)
> +		return IRQ_HANDLED;
> +
> +	connected = mtk_dp_plug_state(mtk_dp);
> +	if (connected || !train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +	else if (!connected || train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;
> +
> +	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +		train_info->cable_plugged_in = true;
> +	} else {
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +		train_info->cable_plugged_in = false;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +	}
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> +}
> +


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-30 10:08     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30 10:08 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool connected;
> +	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
> +	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	train_info->irq_status |= hwirq_status | swirq_status;

You mix software control variable and irq status here. Break each flag
in irq_status to variables in train_info to decouple software control
variable and irq status.

> +
> +	if (!train_info->irq_status)
> +		return IRQ_HANDLED;
> +
> +	connected = mtk_dp_plug_state(mtk_dp);
> +	if (connected || !train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +	else if (!connected || train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;
> +
> +	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +		train_info->cable_plugged_in = true;
> +	} else {
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +		train_info->cable_plugged_in = false;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +	}
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-30 10:08     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30 10:08 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool connected;
> +	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
> +	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	train_info->irq_status |= hwirq_status | swirq_status;

You mix software control variable and irq status here. Break each flag
in irq_status to variables in train_info to decouple software control
variable and irq status.

> +
> +	if (!train_info->irq_status)
> +		return IRQ_HANDLED;
> +
> +	connected = mtk_dp_plug_state(mtk_dp);
> +	if (connected || !train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +	else if (!connected || train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;
> +
> +	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +		train_info->cable_plugged_in = true;
> +	} else {
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +		train_info->cable_plugged_in = false;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +	}
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> +}
> +


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-05-30 10:08     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-05-30 10:08 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Guillaume:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool connected;
> +	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
> +	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	train_info->irq_status |= hwirq_status | swirq_status;

You mix software control variable and irq status here. Break each flag
in irq_status to variables in train_info to decouple software control
variable and irq status.

> +
> +	if (!train_info->irq_status)
> +		return IRQ_HANDLED;
> +
> +	connected = mtk_dp_plug_state(mtk_dp);
> +	if (connected || !train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +	else if (!connected || train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;
> +
> +	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +		train_info->cable_plugged_in = true;
> +	} else {
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +		train_info->cable_plugged_in = false;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +	}
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> +}
> +


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
  2022-05-23 10:47 ` Guillaume Ranquet
                     ` (2 preceding siblings ...)
  (?)
@ 2022-06-02  3:50   ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  3:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi,
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> 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.
> 
> This v10 still has some un-answered comments and TODOs for v11.
> 
> This has been tested sucessfully on a 5.18-next based "vendor
> branch".
> 
> There's a missing dependency in the mediatek clock framework to allow
> a
> mux clock to change it's parent automatically on rate change.
> Without this change, the dpi driver won't properly set the clocks on
> mode change and thus nothing will be displayed on screen.
> 
> Changes from v9:
> - The DP-Phy is back to being a child device of the DP driver (as in
> v8)
> - hot plug detection has been added back to Embedded Display Port...
> as
>   after discussing with mediatek experts, this is needed eventhough
> the
>   Embedded Display port is not un-pluggable
> - rebased on linux-next
> - simplified/split train_handler function, as suggested by Rex
> - added comments on the sleep/delays present in the code
> - removed previous patch introducing retries when receiving AUX_DEFER
> as
>   this is already handled in the dp_aux framework
> - added max-lane and max-linkrate device tree u8 properties instead
> of
>   hardcoded #defines
> 
> Things that are in my todolist for v11:
> - retrieve CK/DE support from panel driver instead of hardcoding it
> into
>   the dpi driver
> - refcount the dp driver "enabled" status for "future proofing"
> - review the drm_dp_helpers for features/functions that have been
>   re-implemented in the mediatek dp drivers
> 
> Older revisions:
> RFC - 
> https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> v1  - 
> https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> v2  - 
> https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> v3  - 
> https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> v4  - 
> https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> v5  - 
> https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> v6  - 
> https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> v7  - 
> https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> v8  - 
> https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> v9  - 
> https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> 
> Functional dependencies are:
> - Add Mediatek Soc DRM (vdosys0) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> - Add MediaTek SoC DRM (vdosys1) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> 
> 
> Guillaume Ranquet (15):
>   drm/edid: Convert cea_sad helper struct to kernelDoc
>   drm/edid: Add cea_sad helpers for freq/length
>   drm/mediatek: dpi: move dpi limits to SoC config
>   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
>   drm/mediatek: dpi: implement a swap_input toggle in SoC config
>   drm/mediatek: dpi: move dimension mask to SoC config
>   drm/mediatek: dpi: move hvsize_mask to SoC config
>   drm/mediatek: dpi: move swap_shift to SoC config
>   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
>   drm/mediatek: dpi: move the csc_enable bit to SoC config
>   drm/mediatek: dpi: Add dpintf support
>   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
>   drm/meditek: dpi: Add matrix_sel helper
>   drm/mediatek: Add mt8195 External DisplayPort support
>   drm/mediatek: DP audio support for mt8195
> 
> Jitao Shi (1):
>   drm/mediatek: add hpd debounce
> 
> Markus Schneider-Pargmann (5):
>   dt-bindings: mediatek,dpi: Add DPINTF compatible
>   dt-bindings: mediatek,dp: Add Display Port binding
>   video/hdmi: Add audio_infoframe packing for DP
>   phy: phy-mtk-dp: Add driver for DP phy
>   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> 
>  .../display/mediatek/mediatek,dp.yaml         |   99 +
>  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
>  MAINTAINERS                                   |    1 +
>  drivers/gpu/drm/drm_edid.c                    |   74 +
>  drivers/gpu/drm/mediatek/Kconfig              |    8 +
>  drivers/gpu/drm/mediatek/Makefile             |    2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> +++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
>  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
>  drivers/phy/mediatek/Kconfig                  |    8 +
>  drivers/phy/mediatek/Makefile                 |    1 +
>  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
>  drivers/video/hdmi.c                          |   82 +-
>  include/drm/dp/drm_dp_helper.h                |    2 +
>  include/drm/drm_edid.h                        |   26 +-
>  include/linux/hdmi.h                          |    7 +-
>  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
>  22 files changed, 4765 insertions(+), 81 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

Hello all,

Due to the resource issue, I will keep upstreaming Guillaume's MT8195
dp/edp series.

I will check the comments for v8/v9/v10 and have some discussion with
you.

Thanks for your all comments.

BRs,
Bo-Chen


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-06-02  3:50   ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  3:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi,
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> 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.
> 
> This v10 still has some un-answered comments and TODOs for v11.
> 
> This has been tested sucessfully on a 5.18-next based "vendor
> branch".
> 
> There's a missing dependency in the mediatek clock framework to allow
> a
> mux clock to change it's parent automatically on rate change.
> Without this change, the dpi driver won't properly set the clocks on
> mode change and thus nothing will be displayed on screen.
> 
> Changes from v9:
> - The DP-Phy is back to being a child device of the DP driver (as in
> v8)
> - hot plug detection has been added back to Embedded Display Port...
> as
>   after discussing with mediatek experts, this is needed eventhough
> the
>   Embedded Display port is not un-pluggable
> - rebased on linux-next
> - simplified/split train_handler function, as suggested by Rex
> - added comments on the sleep/delays present in the code
> - removed previous patch introducing retries when receiving AUX_DEFER
> as
>   this is already handled in the dp_aux framework
> - added max-lane and max-linkrate device tree u8 properties instead
> of
>   hardcoded #defines
> 
> Things that are in my todolist for v11:
> - retrieve CK/DE support from panel driver instead of hardcoding it
> into
>   the dpi driver
> - refcount the dp driver "enabled" status for "future proofing"
> - review the drm_dp_helpers for features/functions that have been
>   re-implemented in the mediatek dp drivers
> 
> Older revisions:
> RFC - 
> https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> v1  - 
> https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> v2  - 
> https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> v3  - 
> https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> v4  - 
> https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> v5  - 
> https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> v6  - 
> https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> v7  - 
> https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> v8  - 
> https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> v9  - 
> https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> 
> Functional dependencies are:
> - Add Mediatek Soc DRM (vdosys0) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> - Add MediaTek SoC DRM (vdosys1) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> 
> 
> Guillaume Ranquet (15):
>   drm/edid: Convert cea_sad helper struct to kernelDoc
>   drm/edid: Add cea_sad helpers for freq/length
>   drm/mediatek: dpi: move dpi limits to SoC config
>   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
>   drm/mediatek: dpi: implement a swap_input toggle in SoC config
>   drm/mediatek: dpi: move dimension mask to SoC config
>   drm/mediatek: dpi: move hvsize_mask to SoC config
>   drm/mediatek: dpi: move swap_shift to SoC config
>   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
>   drm/mediatek: dpi: move the csc_enable bit to SoC config
>   drm/mediatek: dpi: Add dpintf support
>   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
>   drm/meditek: dpi: Add matrix_sel helper
>   drm/mediatek: Add mt8195 External DisplayPort support
>   drm/mediatek: DP audio support for mt8195
> 
> Jitao Shi (1):
>   drm/mediatek: add hpd debounce
> 
> Markus Schneider-Pargmann (5):
>   dt-bindings: mediatek,dpi: Add DPINTF compatible
>   dt-bindings: mediatek,dp: Add Display Port binding
>   video/hdmi: Add audio_infoframe packing for DP
>   phy: phy-mtk-dp: Add driver for DP phy
>   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> 
>  .../display/mediatek/mediatek,dp.yaml         |   99 +
>  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
>  MAINTAINERS                                   |    1 +
>  drivers/gpu/drm/drm_edid.c                    |   74 +
>  drivers/gpu/drm/mediatek/Kconfig              |    8 +
>  drivers/gpu/drm/mediatek/Makefile             |    2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> +++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
>  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
>  drivers/phy/mediatek/Kconfig                  |    8 +
>  drivers/phy/mediatek/Makefile                 |    1 +
>  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
>  drivers/video/hdmi.c                          |   82 +-
>  include/drm/dp/drm_dp_helper.h                |    2 +
>  include/drm/drm_edid.h                        |   26 +-
>  include/linux/hdmi.h                          |    7 +-
>  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
>  22 files changed, 4765 insertions(+), 81 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

Hello all,

Due to the resource issue, I will keep upstreaming Guillaume's MT8195
dp/edp series.

I will check the comments for v8/v9/v10 and have some discussion with
you.

Thanks for your all comments.

BRs,
Bo-Chen


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-06-02  3:50   ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  3:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi,
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> 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.
> 
> This v10 still has some un-answered comments and TODOs for v11.
> 
> This has been tested sucessfully on a 5.18-next based "vendor
> branch".
> 
> There's a missing dependency in the mediatek clock framework to allow
> a
> mux clock to change it's parent automatically on rate change.
> Without this change, the dpi driver won't properly set the clocks on
> mode change and thus nothing will be displayed on screen.
> 
> Changes from v9:
> - The DP-Phy is back to being a child device of the DP driver (as in
> v8)
> - hot plug detection has been added back to Embedded Display Port...
> as
>   after discussing with mediatek experts, this is needed eventhough
> the
>   Embedded Display port is not un-pluggable
> - rebased on linux-next
> - simplified/split train_handler function, as suggested by Rex
> - added comments on the sleep/delays present in the code
> - removed previous patch introducing retries when receiving AUX_DEFER
> as
>   this is already handled in the dp_aux framework
> - added max-lane and max-linkrate device tree u8 properties instead
> of
>   hardcoded #defines
> 
> Things that are in my todolist for v11:
> - retrieve CK/DE support from panel driver instead of hardcoding it
> into
>   the dpi driver
> - refcount the dp driver "enabled" status for "future proofing"
> - review the drm_dp_helpers for features/functions that have been
>   re-implemented in the mediatek dp drivers
> 
> Older revisions:
> RFC - 
> https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> v1  - 
> https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> v2  - 
> https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> v3  - 
> https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> v4  - 
> https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> v5  - 
> https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> v6  - 
> https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> v7  - 
> https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> v8  - 
> https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> v9  - 
> https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> 
> Functional dependencies are:
> - Add Mediatek Soc DRM (vdosys0) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> - Add MediaTek SoC DRM (vdosys1) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> 
> 
> Guillaume Ranquet (15):
>   drm/edid: Convert cea_sad helper struct to kernelDoc
>   drm/edid: Add cea_sad helpers for freq/length
>   drm/mediatek: dpi: move dpi limits to SoC config
>   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
>   drm/mediatek: dpi: implement a swap_input toggle in SoC config
>   drm/mediatek: dpi: move dimension mask to SoC config
>   drm/mediatek: dpi: move hvsize_mask to SoC config
>   drm/mediatek: dpi: move swap_shift to SoC config
>   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
>   drm/mediatek: dpi: move the csc_enable bit to SoC config
>   drm/mediatek: dpi: Add dpintf support
>   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
>   drm/meditek: dpi: Add matrix_sel helper
>   drm/mediatek: Add mt8195 External DisplayPort support
>   drm/mediatek: DP audio support for mt8195
> 
> Jitao Shi (1):
>   drm/mediatek: add hpd debounce
> 
> Markus Schneider-Pargmann (5):
>   dt-bindings: mediatek,dpi: Add DPINTF compatible
>   dt-bindings: mediatek,dp: Add Display Port binding
>   video/hdmi: Add audio_infoframe packing for DP
>   phy: phy-mtk-dp: Add driver for DP phy
>   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> 
>  .../display/mediatek/mediatek,dp.yaml         |   99 +
>  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
>  MAINTAINERS                                   |    1 +
>  drivers/gpu/drm/drm_edid.c                    |   74 +
>  drivers/gpu/drm/mediatek/Kconfig              |    8 +
>  drivers/gpu/drm/mediatek/Makefile             |    2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> +++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
>  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
>  drivers/phy/mediatek/Kconfig                  |    8 +
>  drivers/phy/mediatek/Makefile                 |    1 +
>  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
>  drivers/video/hdmi.c                          |   82 +-
>  include/drm/dp/drm_dp_helper.h                |    2 +
>  include/drm/drm_edid.h                        |   26 +-
>  include/linux/hdmi.h                          |    7 +-
>  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
>  22 files changed, 4765 insertions(+), 81 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

Hello all,

Due to the resource issue, I will keep upstreaming Guillaume's MT8195
dp/edp series.

I will check the comments for v8/v9/v10 and have some discussion with
you.

Thanks for your all comments.

BRs,
Bo-Chen


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-06-02  3:50   ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  3:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi,
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> 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.
> 
> This v10 still has some un-answered comments and TODOs for v11.
> 
> This has been tested sucessfully on a 5.18-next based "vendor
> branch".
> 
> There's a missing dependency in the mediatek clock framework to allow
> a
> mux clock to change it's parent automatically on rate change.
> Without this change, the dpi driver won't properly set the clocks on
> mode change and thus nothing will be displayed on screen.
> 
> Changes from v9:
> - The DP-Phy is back to being a child device of the DP driver (as in
> v8)
> - hot plug detection has been added back to Embedded Display Port...
> as
>   after discussing with mediatek experts, this is needed eventhough
> the
>   Embedded Display port is not un-pluggable
> - rebased on linux-next
> - simplified/split train_handler function, as suggested by Rex
> - added comments on the sleep/delays present in the code
> - removed previous patch introducing retries when receiving AUX_DEFER
> as
>   this is already handled in the dp_aux framework
> - added max-lane and max-linkrate device tree u8 properties instead
> of
>   hardcoded #defines
> 
> Things that are in my todolist for v11:
> - retrieve CK/DE support from panel driver instead of hardcoding it
> into
>   the dpi driver
> - refcount the dp driver "enabled" status for "future proofing"
> - review the drm_dp_helpers for features/functions that have been
>   re-implemented in the mediatek dp drivers
> 
> Older revisions:
> RFC - 
> https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> v1  - 
> https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> v2  - 
> https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> v3  - 
> https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> v4  - 
> https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> v5  - 
> https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> v6  - 
> https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> v7  - 
> https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> v8  - 
> https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> v9  - 
> https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> 
> Functional dependencies are:
> - Add Mediatek Soc DRM (vdosys0) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> - Add MediaTek SoC DRM (vdosys1) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> 
> 
> Guillaume Ranquet (15):
>   drm/edid: Convert cea_sad helper struct to kernelDoc
>   drm/edid: Add cea_sad helpers for freq/length
>   drm/mediatek: dpi: move dpi limits to SoC config
>   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
>   drm/mediatek: dpi: implement a swap_input toggle in SoC config
>   drm/mediatek: dpi: move dimension mask to SoC config
>   drm/mediatek: dpi: move hvsize_mask to SoC config
>   drm/mediatek: dpi: move swap_shift to SoC config
>   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
>   drm/mediatek: dpi: move the csc_enable bit to SoC config
>   drm/mediatek: dpi: Add dpintf support
>   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
>   drm/meditek: dpi: Add matrix_sel helper
>   drm/mediatek: Add mt8195 External DisplayPort support
>   drm/mediatek: DP audio support for mt8195
> 
> Jitao Shi (1):
>   drm/mediatek: add hpd debounce
> 
> Markus Schneider-Pargmann (5):
>   dt-bindings: mediatek,dpi: Add DPINTF compatible
>   dt-bindings: mediatek,dp: Add Display Port binding
>   video/hdmi: Add audio_infoframe packing for DP
>   phy: phy-mtk-dp: Add driver for DP phy
>   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> 
>  .../display/mediatek/mediatek,dp.yaml         |   99 +
>  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
>  MAINTAINERS                                   |    1 +
>  drivers/gpu/drm/drm_edid.c                    |   74 +
>  drivers/gpu/drm/mediatek/Kconfig              |    8 +
>  drivers/gpu/drm/mediatek/Makefile             |    2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> +++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
>  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
>  drivers/phy/mediatek/Kconfig                  |    8 +
>  drivers/phy/mediatek/Makefile                 |    1 +
>  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
>  drivers/video/hdmi.c                          |   82 +-
>  include/drm/dp/drm_dp_helper.h                |    2 +
>  include/drm/drm_edid.h                        |   26 +-
>  include/linux/hdmi.h                          |    7 +-
>  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
>  22 files changed, 4765 insertions(+), 81 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

Hello all,

Due to the resource issue, I will keep upstreaming Guillaume's MT8195
dp/edp series.

I will check the comments for v8/v9/v10 and have some discussion with
you.

Thanks for your all comments.

BRs,
Bo-Chen


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-06-02  3:50   ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  3:50 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi,
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> 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.
> 
> This v10 still has some un-answered comments and TODOs for v11.
> 
> This has been tested sucessfully on a 5.18-next based "vendor
> branch".
> 
> There's a missing dependency in the mediatek clock framework to allow
> a
> mux clock to change it's parent automatically on rate change.
> Without this change, the dpi driver won't properly set the clocks on
> mode change and thus nothing will be displayed on screen.
> 
> Changes from v9:
> - The DP-Phy is back to being a child device of the DP driver (as in
> v8)
> - hot plug detection has been added back to Embedded Display Port...
> as
>   after discussing with mediatek experts, this is needed eventhough
> the
>   Embedded Display port is not un-pluggable
> - rebased on linux-next
> - simplified/split train_handler function, as suggested by Rex
> - added comments on the sleep/delays present in the code
> - removed previous patch introducing retries when receiving AUX_DEFER
> as
>   this is already handled in the dp_aux framework
> - added max-lane and max-linkrate device tree u8 properties instead
> of
>   hardcoded #defines
> 
> Things that are in my todolist for v11:
> - retrieve CK/DE support from panel driver instead of hardcoding it
> into
>   the dpi driver
> - refcount the dp driver "enabled" status for "future proofing"
> - review the drm_dp_helpers for features/functions that have been
>   re-implemented in the mediatek dp drivers
> 
> Older revisions:
> RFC - 
> https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> v1  - 
> https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> v2  - 
> https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> v3  - 
> https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> v4  - 
> https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> v5  - 
> https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> v6  - 
> https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> v7  - 
> https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> v8  - 
> https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> v9  - 
> https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> 
> Functional dependencies are:
> - Add Mediatek Soc DRM (vdosys0) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> - Add MediaTek SoC DRM (vdosys1) support for mt8195
>   
> https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> 
> 
> Guillaume Ranquet (15):
>   drm/edid: Convert cea_sad helper struct to kernelDoc
>   drm/edid: Add cea_sad helpers for freq/length
>   drm/mediatek: dpi: move dpi limits to SoC config
>   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
>   drm/mediatek: dpi: implement a swap_input toggle in SoC config
>   drm/mediatek: dpi: move dimension mask to SoC config
>   drm/mediatek: dpi: move hvsize_mask to SoC config
>   drm/mediatek: dpi: move swap_shift to SoC config
>   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
>   drm/mediatek: dpi: move the csc_enable bit to SoC config
>   drm/mediatek: dpi: Add dpintf support
>   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
>   drm/meditek: dpi: Add matrix_sel helper
>   drm/mediatek: Add mt8195 External DisplayPort support
>   drm/mediatek: DP audio support for mt8195
> 
> Jitao Shi (1):
>   drm/mediatek: add hpd debounce
> 
> Markus Schneider-Pargmann (5):
>   dt-bindings: mediatek,dpi: Add DPINTF compatible
>   dt-bindings: mediatek,dp: Add Display Port binding
>   video/hdmi: Add audio_infoframe packing for DP
>   phy: phy-mtk-dp: Add driver for DP phy
>   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> 
>  .../display/mediatek/mediatek,dp.yaml         |   99 +
>  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
>  MAINTAINERS                                   |    1 +
>  drivers/gpu/drm/drm_edid.c                    |   74 +
>  drivers/gpu/drm/mediatek/Kconfig              |    8 +
>  drivers/gpu/drm/mediatek/Makefile             |    2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> +++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
>  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
>  drivers/phy/mediatek/Kconfig                  |    8 +
>  drivers/phy/mediatek/Makefile                 |    1 +
>  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
>  drivers/video/hdmi.c                          |   82 +-
>  include/drm/dp/drm_dp_helper.h                |    2 +
>  include/drm/drm_edid.h                        |   26 +-
>  include/linux/hdmi.h                          |    7 +-
>  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
>  22 files changed, 4765 insertions(+), 81 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

Hello all,

Due to the resource issue, I will keep upstreaming Guillaume's MT8195
dp/edp series.

I will check the comments for v8/v9/v10 and have some discussion with
you.

Thanks for your all comments.

BRs,
Bo-Chen


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
  2022-06-02  3:50   ` Rex-BC Chen
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-02  5:31     ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  5:31 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu (胡俊光),
	Jitao Shi (石记涛),
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-02 at 11:50 +0800, Rex-BC Chen wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > 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.
> > 
> > This v10 still has some un-answered comments and TODOs for v11.
> > 
> > This has been tested sucessfully on a 5.18-next based "vendor
> > branch".
> > 
> > There's a missing dependency in the mediatek clock framework to
> > allow
> > a
> > mux clock to change it's parent automatically on rate change.
> > Without this change, the dpi driver won't properly set the clocks
> > on
> > mode change and thus nothing will be displayed on screen.
> > 
> > Changes from v9:
> > - The DP-Phy is back to being a child device of the DP driver (as
> > in
> > v8)
> > - hot plug detection has been added back to Embedded Display
> > Port...
> > as
> >   after discussing with mediatek experts, this is needed eventhough
> > the
> >   Embedded Display port is not un-pluggable
> > - rebased on linux-next
> > - simplified/split train_handler function, as suggested by Rex
> > - added comments on the sleep/delays present in the code
> > - removed previous patch introducing retries when receiving
> > AUX_DEFER
> > as
> >   this is already handled in the dp_aux framework
> > - added max-lane and max-linkrate device tree u8 properties instead
> > of
> >   hardcoded #defines
> > 
> > Things that are in my todolist for v11:
> > - retrieve CK/DE support from panel driver instead of hardcoding it
> > into
> >   the dpi driver
> > - refcount the dp driver "enabled" status for "future proofing"
> > - review the drm_dp_helpers for features/functions that have been
> >   re-implemented in the mediatek dp drivers
> > 
> > Older revisions:
> > RFC - 
> > 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> > v1  - 
> > 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> > v2  - 
> > 
https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> > v3  - 
> > 
https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> > v4  - 
> > 
https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> > v5  - 
> > 
https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> > v6  - 
> > 
https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> > v7  - 
> > 
https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> > v8  - 
> > 
https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> > v9  - 
> > 
https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> > 
> > Functional dependencies are:
> > - Add Mediatek Soc DRM (vdosys0) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> > - Add MediaTek SoC DRM (vdosys1) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> > 
> > 
> > Guillaume Ranquet (15):
> >   drm/edid: Convert cea_sad helper struct to kernelDoc
> >   drm/edid: Add cea_sad helpers for freq/length
> >   drm/mediatek: dpi: move dpi limits to SoC config
> >   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
> >   drm/mediatek: dpi: implement a swap_input toggle in SoC config
> >   drm/mediatek: dpi: move dimension mask to SoC config
> >   drm/mediatek: dpi: move hvsize_mask to SoC config
> >   drm/mediatek: dpi: move swap_shift to SoC config
> >   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
> >   drm/mediatek: dpi: move the csc_enable bit to SoC config
> >   drm/mediatek: dpi: Add dpintf support
> >   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
> >   drm/meditek: dpi: Add matrix_sel helper
> >   drm/mediatek: Add mt8195 External DisplayPort support
> >   drm/mediatek: DP audio support for mt8195
> > 
> > Jitao Shi (1):
> >   drm/mediatek: add hpd debounce
> > 
> > Markus Schneider-Pargmann (5):
> >   dt-bindings: mediatek,dpi: Add DPINTF compatible
> >   dt-bindings: mediatek,dp: Add Display Port binding
> >   video/hdmi: Add audio_infoframe packing for DP
> >   phy: phy-mtk-dp: Add driver for DP phy
> >   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> > 
> >  .../display/mediatek/mediatek,dp.yaml         |   99 +
> >  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
> >  MAINTAINERS                                   |    1 +
> >  drivers/gpu/drm/drm_edid.c                    |   74 +
> >  drivers/gpu/drm/mediatek/Kconfig              |    8 +
> >  drivers/gpu/drm/mediatek/Makefile             |    2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> > +++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
> >  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
> >  drivers/phy/mediatek/Kconfig                  |    8 +
> >  drivers/phy/mediatek/Makefile                 |    1 +
> >  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
> >  drivers/video/hdmi.c                          |   82 +-
> >  include/drm/dp/drm_dp_helper.h                |    2 +
> >  include/drm/drm_edid.h                        |   26 +-
> >  include/linux/hdmi.h                          |    7 +-
> >  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
> >  22 files changed, 4765 insertions(+), 81 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
> 
> Hello all,
> 
> Due to the resource issue, I will keep upstreaming Guillaume's MT8195
> dp/edp series.
> 
> I will check the comments for v8/v9/v10 and have some discussion with
> you.
> 
> Thanks for your all comments.
> 
> BRs,
> Bo-Chen
> 

Hello all,

Because the patches of dp_intf seem to be almost completed, I want to
split this series into two series:
dp_intf and edp/dp.

It will be easier to review and maintain this series.

Thanks!

BRs,
Bo-Chen


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-06-02  5:31     ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  5:31 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu (胡俊光),
	Jitao Shi (石记涛),
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-02 at 11:50 +0800, Rex-BC Chen wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > 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.
> > 
> > This v10 still has some un-answered comments and TODOs for v11.
> > 
> > This has been tested sucessfully on a 5.18-next based "vendor
> > branch".
> > 
> > There's a missing dependency in the mediatek clock framework to
> > allow
> > a
> > mux clock to change it's parent automatically on rate change.
> > Without this change, the dpi driver won't properly set the clocks
> > on
> > mode change and thus nothing will be displayed on screen.
> > 
> > Changes from v9:
> > - The DP-Phy is back to being a child device of the DP driver (as
> > in
> > v8)
> > - hot plug detection has been added back to Embedded Display
> > Port...
> > as
> >   after discussing with mediatek experts, this is needed eventhough
> > the
> >   Embedded Display port is not un-pluggable
> > - rebased on linux-next
> > - simplified/split train_handler function, as suggested by Rex
> > - added comments on the sleep/delays present in the code
> > - removed previous patch introducing retries when receiving
> > AUX_DEFER
> > as
> >   this is already handled in the dp_aux framework
> > - added max-lane and max-linkrate device tree u8 properties instead
> > of
> >   hardcoded #defines
> > 
> > Things that are in my todolist for v11:
> > - retrieve CK/DE support from panel driver instead of hardcoding it
> > into
> >   the dpi driver
> > - refcount the dp driver "enabled" status for "future proofing"
> > - review the drm_dp_helpers for features/functions that have been
> >   re-implemented in the mediatek dp drivers
> > 
> > Older revisions:
> > RFC - 
> > 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> > v1  - 
> > 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> > v2  - 
> > 
https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> > v3  - 
> > 
https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> > v4  - 
> > 
https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> > v5  - 
> > 
https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> > v6  - 
> > 
https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> > v7  - 
> > 
https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> > v8  - 
> > 
https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> > v9  - 
> > 
https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> > 
> > Functional dependencies are:
> > - Add Mediatek Soc DRM (vdosys0) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> > - Add MediaTek SoC DRM (vdosys1) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> > 
> > 
> > Guillaume Ranquet (15):
> >   drm/edid: Convert cea_sad helper struct to kernelDoc
> >   drm/edid: Add cea_sad helpers for freq/length
> >   drm/mediatek: dpi: move dpi limits to SoC config
> >   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
> >   drm/mediatek: dpi: implement a swap_input toggle in SoC config
> >   drm/mediatek: dpi: move dimension mask to SoC config
> >   drm/mediatek: dpi: move hvsize_mask to SoC config
> >   drm/mediatek: dpi: move swap_shift to SoC config
> >   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
> >   drm/mediatek: dpi: move the csc_enable bit to SoC config
> >   drm/mediatek: dpi: Add dpintf support
> >   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
> >   drm/meditek: dpi: Add matrix_sel helper
> >   drm/mediatek: Add mt8195 External DisplayPort support
> >   drm/mediatek: DP audio support for mt8195
> > 
> > Jitao Shi (1):
> >   drm/mediatek: add hpd debounce
> > 
> > Markus Schneider-Pargmann (5):
> >   dt-bindings: mediatek,dpi: Add DPINTF compatible
> >   dt-bindings: mediatek,dp: Add Display Port binding
> >   video/hdmi: Add audio_infoframe packing for DP
> >   phy: phy-mtk-dp: Add driver for DP phy
> >   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> > 
> >  .../display/mediatek/mediatek,dp.yaml         |   99 +
> >  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
> >  MAINTAINERS                                   |    1 +
> >  drivers/gpu/drm/drm_edid.c                    |   74 +
> >  drivers/gpu/drm/mediatek/Kconfig              |    8 +
> >  drivers/gpu/drm/mediatek/Makefile             |    2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> > +++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
> >  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
> >  drivers/phy/mediatek/Kconfig                  |    8 +
> >  drivers/phy/mediatek/Makefile                 |    1 +
> >  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
> >  drivers/video/hdmi.c                          |   82 +-
> >  include/drm/dp/drm_dp_helper.h                |    2 +
> >  include/drm/drm_edid.h                        |   26 +-
> >  include/linux/hdmi.h                          |    7 +-
> >  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
> >  22 files changed, 4765 insertions(+), 81 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
> 
> Hello all,
> 
> Due to the resource issue, I will keep upstreaming Guillaume's MT8195
> dp/edp series.
> 
> I will check the comments for v8/v9/v10 and have some discussion with
> you.
> 
> Thanks for your all comments.
> 
> BRs,
> Bo-Chen
> 

Hello all,

Because the patches of dp_intf seem to be almost completed, I want to
split this series into two series:
dp_intf and edp/dp.

It will be easier to review and maintain this series.

Thanks!

BRs,
Bo-Chen


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-06-02  5:31     ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  5:31 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu (胡俊光),
	Jitao Shi (石记涛),
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

On Thu, 2022-06-02 at 11:50 +0800, Rex-BC Chen wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > 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.
> > 
> > This v10 still has some un-answered comments and TODOs for v11.
> > 
> > This has been tested sucessfully on a 5.18-next based "vendor
> > branch".
> > 
> > There's a missing dependency in the mediatek clock framework to
> > allow
> > a
> > mux clock to change it's parent automatically on rate change.
> > Without this change, the dpi driver won't properly set the clocks
> > on
> > mode change and thus nothing will be displayed on screen.
> > 
> > Changes from v9:
> > - The DP-Phy is back to being a child device of the DP driver (as
> > in
> > v8)
> > - hot plug detection has been added back to Embedded Display
> > Port...
> > as
> >   after discussing with mediatek experts, this is needed eventhough
> > the
> >   Embedded Display port is not un-pluggable
> > - rebased on linux-next
> > - simplified/split train_handler function, as suggested by Rex
> > - added comments on the sleep/delays present in the code
> > - removed previous patch introducing retries when receiving
> > AUX_DEFER
> > as
> >   this is already handled in the dp_aux framework
> > - added max-lane and max-linkrate device tree u8 properties instead
> > of
> >   hardcoded #defines
> > 
> > Things that are in my todolist for v11:
> > - retrieve CK/DE support from panel driver instead of hardcoding it
> > into
> >   the dpi driver
> > - refcount the dp driver "enabled" status for "future proofing"
> > - review the drm_dp_helpers for features/functions that have been
> >   re-implemented in the mediatek dp drivers
> > 
> > Older revisions:
> > RFC - 
> > 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> > v1  - 
> > 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> > v2  - 
> > 
https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> > v3  - 
> > 
https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> > v4  - 
> > 
https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> > v5  - 
> > 
https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> > v6  - 
> > 
https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> > v7  - 
> > 
https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> > v8  - 
> > 
https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> > v9  - 
> > 
https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> > 
> > Functional dependencies are:
> > - Add Mediatek Soc DRM (vdosys0) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> > - Add MediaTek SoC DRM (vdosys1) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> > 
> > 
> > Guillaume Ranquet (15):
> >   drm/edid: Convert cea_sad helper struct to kernelDoc
> >   drm/edid: Add cea_sad helpers for freq/length
> >   drm/mediatek: dpi: move dpi limits to SoC config
> >   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
> >   drm/mediatek: dpi: implement a swap_input toggle in SoC config
> >   drm/mediatek: dpi: move dimension mask to SoC config
> >   drm/mediatek: dpi: move hvsize_mask to SoC config
> >   drm/mediatek: dpi: move swap_shift to SoC config
> >   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
> >   drm/mediatek: dpi: move the csc_enable bit to SoC config
> >   drm/mediatek: dpi: Add dpintf support
> >   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
> >   drm/meditek: dpi: Add matrix_sel helper
> >   drm/mediatek: Add mt8195 External DisplayPort support
> >   drm/mediatek: DP audio support for mt8195
> > 
> > Jitao Shi (1):
> >   drm/mediatek: add hpd debounce
> > 
> > Markus Schneider-Pargmann (5):
> >   dt-bindings: mediatek,dpi: Add DPINTF compatible
> >   dt-bindings: mediatek,dp: Add Display Port binding
> >   video/hdmi: Add audio_infoframe packing for DP
> >   phy: phy-mtk-dp: Add driver for DP phy
> >   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> > 
> >  .../display/mediatek/mediatek,dp.yaml         |   99 +
> >  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
> >  MAINTAINERS                                   |    1 +
> >  drivers/gpu/drm/drm_edid.c                    |   74 +
> >  drivers/gpu/drm/mediatek/Kconfig              |    8 +
> >  drivers/gpu/drm/mediatek/Makefile             |    2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> > +++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
> >  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
> >  drivers/phy/mediatek/Kconfig                  |    8 +
> >  drivers/phy/mediatek/Makefile                 |    1 +
> >  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
> >  drivers/video/hdmi.c                          |   82 +-
> >  include/drm/dp/drm_dp_helper.h                |    2 +
> >  include/drm/drm_edid.h                        |   26 +-
> >  include/linux/hdmi.h                          |    7 +-
> >  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
> >  22 files changed, 4765 insertions(+), 81 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
> 
> Hello all,
> 
> Due to the resource issue, I will keep upstreaming Guillaume's MT8195
> dp/edp series.
> 
> I will check the comments for v8/v9/v10 and have some discussion with
> you.
> 
> Thanks for your all comments.
> 
> BRs,
> Bo-Chen
> 

Hello all,

Because the patches of dp_intf seem to be almost completed, I want to
split this series into two series:
dp_intf and edp/dp.

It will be easier to review and maintain this series.

Thanks!

BRs,
Bo-Chen


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-06-02  5:31     ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  5:31 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu (胡俊光),
	Jitao Shi (石记涛),
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-02 at 11:50 +0800, Rex-BC Chen wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > 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.
> > 
> > This v10 still has some un-answered comments and TODOs for v11.
> > 
> > This has been tested sucessfully on a 5.18-next based "vendor
> > branch".
> > 
> > There's a missing dependency in the mediatek clock framework to
> > allow
> > a
> > mux clock to change it's parent automatically on rate change.
> > Without this change, the dpi driver won't properly set the clocks
> > on
> > mode change and thus nothing will be displayed on screen.
> > 
> > Changes from v9:
> > - The DP-Phy is back to being a child device of the DP driver (as
> > in
> > v8)
> > - hot plug detection has been added back to Embedded Display
> > Port...
> > as
> >   after discussing with mediatek experts, this is needed eventhough
> > the
> >   Embedded Display port is not un-pluggable
> > - rebased on linux-next
> > - simplified/split train_handler function, as suggested by Rex
> > - added comments on the sleep/delays present in the code
> > - removed previous patch introducing retries when receiving
> > AUX_DEFER
> > as
> >   this is already handled in the dp_aux framework
> > - added max-lane and max-linkrate device tree u8 properties instead
> > of
> >   hardcoded #defines
> > 
> > Things that are in my todolist for v11:
> > - retrieve CK/DE support from panel driver instead of hardcoding it
> > into
> >   the dpi driver
> > - refcount the dp driver "enabled" status for "future proofing"
> > - review the drm_dp_helpers for features/functions that have been
> >   re-implemented in the mediatek dp drivers
> > 
> > Older revisions:
> > RFC - 
> > 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> > v1  - 
> > 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> > v2  - 
> > 
https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> > v3  - 
> > 
https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> > v4  - 
> > 
https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> > v5  - 
> > 
https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> > v6  - 
> > 
https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> > v7  - 
> > 
https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> > v8  - 
> > 
https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> > v9  - 
> > 
https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> > 
> > Functional dependencies are:
> > - Add Mediatek Soc DRM (vdosys0) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> > - Add MediaTek SoC DRM (vdosys1) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> > 
> > 
> > Guillaume Ranquet (15):
> >   drm/edid: Convert cea_sad helper struct to kernelDoc
> >   drm/edid: Add cea_sad helpers for freq/length
> >   drm/mediatek: dpi: move dpi limits to SoC config
> >   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
> >   drm/mediatek: dpi: implement a swap_input toggle in SoC config
> >   drm/mediatek: dpi: move dimension mask to SoC config
> >   drm/mediatek: dpi: move hvsize_mask to SoC config
> >   drm/mediatek: dpi: move swap_shift to SoC config
> >   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
> >   drm/mediatek: dpi: move the csc_enable bit to SoC config
> >   drm/mediatek: dpi: Add dpintf support
> >   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
> >   drm/meditek: dpi: Add matrix_sel helper
> >   drm/mediatek: Add mt8195 External DisplayPort support
> >   drm/mediatek: DP audio support for mt8195
> > 
> > Jitao Shi (1):
> >   drm/mediatek: add hpd debounce
> > 
> > Markus Schneider-Pargmann (5):
> >   dt-bindings: mediatek,dpi: Add DPINTF compatible
> >   dt-bindings: mediatek,dp: Add Display Port binding
> >   video/hdmi: Add audio_infoframe packing for DP
> >   phy: phy-mtk-dp: Add driver for DP phy
> >   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> > 
> >  .../display/mediatek/mediatek,dp.yaml         |   99 +
> >  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
> >  MAINTAINERS                                   |    1 +
> >  drivers/gpu/drm/drm_edid.c                    |   74 +
> >  drivers/gpu/drm/mediatek/Kconfig              |    8 +
> >  drivers/gpu/drm/mediatek/Makefile             |    2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> > +++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
> >  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
> >  drivers/phy/mediatek/Kconfig                  |    8 +
> >  drivers/phy/mediatek/Makefile                 |    1 +
> >  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
> >  drivers/video/hdmi.c                          |   82 +-
> >  include/drm/dp/drm_dp_helper.h                |    2 +
> >  include/drm/drm_edid.h                        |   26 +-
> >  include/linux/hdmi.h                          |    7 +-
> >  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
> >  22 files changed, 4765 insertions(+), 81 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
> 
> Hello all,
> 
> Due to the resource issue, I will keep upstreaming Guillaume's MT8195
> dp/edp series.
> 
> I will check the comments for v8/v9/v10 and have some discussion with
> you.
> 
> Thanks for your all comments.
> 
> BRs,
> Bo-Chen
> 

Hello all,

Because the patches of dp_intf seem to be almost completed, I want to
split this series into two series:
dp_intf and edp/dp.

It will be easier to review and maintain this series.

Thanks!

BRs,
Bo-Chen


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver
@ 2022-06-02  5:31     ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02  5:31 UTC (permalink / raw)
  To: Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	CK Hu (胡俊光),
	Jitao Shi (石记涛),
	angelogioacchino.delregno, Project_Global_Chrome_Upstream_Group,
	maxime
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-02 at 11:50 +0800, Rex-BC Chen wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > 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.
> > 
> > This v10 still has some un-answered comments and TODOs for v11.
> > 
> > This has been tested sucessfully on a 5.18-next based "vendor
> > branch".
> > 
> > There's a missing dependency in the mediatek clock framework to
> > allow
> > a
> > mux clock to change it's parent automatically on rate change.
> > Without this change, the dpi driver won't properly set the clocks
> > on
> > mode change and thus nothing will be displayed on screen.
> > 
> > Changes from v9:
> > - The DP-Phy is back to being a child device of the DP driver (as
> > in
> > v8)
> > - hot plug detection has been added back to Embedded Display
> > Port...
> > as
> >   after discussing with mediatek experts, this is needed eventhough
> > the
> >   Embedded Display port is not un-pluggable
> > - rebased on linux-next
> > - simplified/split train_handler function, as suggested by Rex
> > - added comments on the sleep/delays present in the code
> > - removed previous patch introducing retries when receiving
> > AUX_DEFER
> > as
> >   this is already handled in the dp_aux framework
> > - added max-lane and max-linkrate device tree u8 properties instead
> > of
> >   hardcoded #defines
> > 
> > Things that are in my todolist for v11:
> > - retrieve CK/DE support from panel driver instead of hardcoding it
> > into
> >   the dpi driver
> > - refcount the dp driver "enabled" status for "future proofing"
> > - review the drm_dp_helpers for features/functions that have been
> >   re-implemented in the mediatek dp drivers
> > 
> > Older revisions:
> > RFC - 
> > 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-msp@baylibre.com/
> > v1  - 
> > 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-msp@baylibre.com/
> > v2  - 
> > 
https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-msp@baylibre.com/
> > v3  - 
> > 
https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-msp@baylibre.com/
> > v4  - 
> > 
https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-msp@baylibre.com/
> > v5  - 
> > 
https://lore.kernel.org/all/20211021092707.3562523-1-msp@baylibre.com/
> > v6  - 
> > 
https://lore.kernel.org/linux-mediatek/20211110130623.20553-1-granquet@baylibre.com/
> > v7  - 
> > 
https://lore.kernel.org/linux-mediatek/20211217150854.2081-1-granquet@baylibre.com/
> > v8  - 
> > 
https://lore.kernel.org/linux-mediatek/20220218145437.18563-1-granquet@baylibre.com/
> > v9  - 
> > 
https://lore.kernel.org/all/20220327223927.20848-1-granquet@baylibre.com/
> > 
> > Functional dependencies are:
> > - Add Mediatek Soc DRM (vdosys0) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220419094143.9561-2-jason-jh.lin@mediatek.com/
> > - Add MediaTek SoC DRM (vdosys1) support for mt8195
> >   
> > 
https://lore.kernel.org/linux-mediatek/20220512053128.31415-1-nancy.lin@mediatek.com/
> > 
> > 
> > Guillaume Ranquet (15):
> >   drm/edid: Convert cea_sad helper struct to kernelDoc
> >   drm/edid: Add cea_sad helpers for freq/length
> >   drm/mediatek: dpi: move dpi limits to SoC config
> >   drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
> >   drm/mediatek: dpi: implement a swap_input toggle in SoC config
> >   drm/mediatek: dpi: move dimension mask to SoC config
> >   drm/mediatek: dpi: move hvsize_mask to SoC config
> >   drm/mediatek: dpi: move swap_shift to SoC config
> >   drm/mediatek: dpi: move the yuv422_en_bit to SoC config
> >   drm/mediatek: dpi: move the csc_enable bit to SoC config
> >   drm/mediatek: dpi: Add dpintf support
> >   drm/mediatek: dpi: Only enable dpi after the bridge is enabled
> >   drm/meditek: dpi: Add matrix_sel helper
> >   drm/mediatek: Add mt8195 External DisplayPort support
> >   drm/mediatek: DP audio support for mt8195
> > 
> > Jitao Shi (1):
> >   drm/mediatek: add hpd debounce
> > 
> > Markus Schneider-Pargmann (5):
> >   dt-bindings: mediatek,dpi: Add DPINTF compatible
> >   dt-bindings: mediatek,dp: Add Display Port binding
> >   video/hdmi: Add audio_infoframe packing for DP
> >   phy: phy-mtk-dp: Add driver for DP phy
> >   drm/mediatek: Add mt8195 Embedded DisplayPort driver
> > 
> >  .../display/mediatek/mediatek,dp.yaml         |   99 +
> >  .../display/mediatek/mediatek,dpi.yaml        |   13 +-
> >  MAINTAINERS                                   |    1 +
> >  drivers/gpu/drm/drm_edid.c                    |   74 +
> >  drivers/gpu/drm/mediatek/Kconfig              |    8 +
> >  drivers/gpu/drm/mediatek/Makefile             |    2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c             | 3419
> > +++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h         |  570 +++
> >  drivers/gpu/drm/mediatek/mtk_dpi.c            |  272 +-
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   38 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |    8 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |    1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    8 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |    3 +
> >  drivers/phy/mediatek/Kconfig                  |    8 +
> >  drivers/phy/mediatek/Makefile                 |    1 +
> >  drivers/phy/mediatek/phy-mtk-dp.c             |  200 +
> >  drivers/video/hdmi.c                          |   82 +-
> >  include/drm/dp/drm_dp_helper.h                |    2 +
> >  include/drm/drm_edid.h                        |   26 +-
> >  include/linux/hdmi.h                          |    7 +-
> >  include/linux/soc/mediatek/mtk-mmsys.h        |    4 +-
> >  22 files changed, 4765 insertions(+), 81 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
> 
> Hello all,
> 
> Due to the resource issue, I will keep upstreaming Guillaume's MT8195
> dp/edp series.
> 
> I will check the comments for v8/v9/v10 and have some discussion with
> you.
> 
> Thanks for your all comments.
> 
> BRs,
> Bo-Chen
> 

Hello all,

Because the patches of dp_intf seem to be almost completed, I want to
split this series into two series:
dp_intf and edp/dp.

It will be easier to review and maintain this series.

Thanks!

BRs,
Bo-Chen


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-02  5:48     ` Christophe JAILLET
  -1 siblings, 0 replies; 450+ messages in thread
From: Christophe JAILLET @ 2022-06-02  5:48 UTC (permalink / raw)
  To: granquet
  Cc: airlied, chunfeng.yun, chunkuang.hu, ck.hu, daniel, deller,
	devicetree, dri-devel, jitao.shi, kishon, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-fbdev, linux-kernel, linux-mediatek,
	linux-phy, maarten.lankhorst, matthias.bgg, mripard, msp,
	p.zabel, robh+dt, tzimmermann, vkoul

Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Guillaume Ranquet <granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   

Hi,

belwo the error handling path looks odd. (both where we goto, and the 
order of the clk_disable_unprepare() in the error handling path.

just my 2c,

CJ

> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;

[...]

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-02  5:48     ` Christophe JAILLET
  0 siblings, 0 replies; 450+ messages in thread
From: Christophe JAILLET @ 2022-06-02  5:48 UTC (permalink / raw)
  To: granquet
  Cc: airlied, chunfeng.yun, chunkuang.hu, ck.hu, daniel, deller,
	devicetree, dri-devel, jitao.shi, kishon, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-fbdev, linux-kernel, linux-mediatek,
	linux-phy, maarten.lankhorst, matthias.bgg, mripard, msp,
	p.zabel, robh+dt, tzimmermann, vkoul

Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Guillaume Ranquet <granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   

Hi,

belwo the error handling path looks odd. (both where we goto, and the 
order of the clk_disable_unprepare() in the error handling path.

just my 2c,

CJ

> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;

[...]

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-02  5:48     ` Christophe JAILLET
  0 siblings, 0 replies; 450+ messages in thread
From: Christophe JAILLET @ 2022-06-02  5:48 UTC (permalink / raw)
  To: granquet
  Cc: linux-fbdev, devicetree, airlied, dri-devel,
	krzysztof.kozlowski+dt, linux-phy, deller, kishon, chunkuang.hu,
	jitao.shi, msp, chunfeng.yun, robh+dt, linux-mediatek,
	matthias.bgg, linux-arm-kernel, tzimmermann, linux-kernel, vkoul

Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Guillaume Ranquet <granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   

Hi,

belwo the error handling path looks odd. (both where we goto, and the 
order of the clk_disable_unprepare() in the error handling path.

just my 2c,

CJ

> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;

[...]

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-02  5:48     ` Christophe JAILLET
  0 siblings, 0 replies; 450+ messages in thread
From: Christophe JAILLET @ 2022-06-02  5:48 UTC (permalink / raw)
  To: granquet
  Cc: airlied, chunfeng.yun, chunkuang.hu, ck.hu, daniel, deller,
	devicetree, dri-devel, jitao.shi, kishon, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-fbdev, linux-kernel, linux-mediatek,
	linux-phy, maarten.lankhorst, matthias.bgg, mripard, msp,
	p.zabel, robh+dt, tzimmermann, vkoul

Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Guillaume Ranquet <granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   

Hi,

belwo the error handling path looks odd. (both where we goto, and the 
order of the clk_disable_unprepare() in the error handling path.

just my 2c,

CJ

> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;

[...]

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-02  5:48     ` Christophe JAILLET
  0 siblings, 0 replies; 450+ messages in thread
From: Christophe JAILLET @ 2022-06-02  5:48 UTC (permalink / raw)
  To: granquet
  Cc: airlied, chunfeng.yun, chunkuang.hu, ck.hu, daniel, deller,
	devicetree, dri-devel, jitao.shi, kishon, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-fbdev, linux-kernel, linux-mediatek,
	linux-phy, maarten.lankhorst, matthias.bgg, mripard, msp,
	p.zabel, robh+dt, tzimmermann, vkoul

Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Guillaume Ranquet <granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
>   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126 +++++++++++++++++---
>   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
>   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      |   4 +-
>   6 files changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index eb969c5c5c2e..763bfb700135 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -71,6 +71,7 @@ struct mtk_dpi {
>   	void __iomem *regs;
>   	struct device *dev;
>   	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>   	struct clk *pixel_clk;
>   	struct clk *tvd_clk;
>   	int irq;
> @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
>   	const u32 *output_fmts;
>   	u32 num_output_fmts;
>   	bool is_ck_de_pol;
> +	bool is_dpintf;
>   	bool swap_input_support;
>   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */
>   	u32 dimension_mask;
> @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>   	mtk_dpi_disable(dpi);
>   	clk_disable_unprepare(dpi->pixel_clk);
>   	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +	clk_disable_unprepare(dpi->tvd_clk);
>   }
>   
>   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	if (++dpi->refcount != 1)
>   		return 0;
>   

Hi,

belwo the error handling path looks odd. (both where we goto, and the 
order of the clk_disable_unprepare() in the error handling path.

just my 2c,

CJ

> +	ret = clk_prepare_enable(dpi->tvd_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +		goto err_pixel;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->engine_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
>   		goto err_refcount;
>   	}
>   
> +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +		goto err_ck_cg;
> +	}
> +
>   	ret = clk_prepare_enable(dpi->pixel_clk);
>   	if (ret) {
>   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>   	return 0;
>   
>   err_pixel:
> +	clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_ck_cg:
>   	clk_disable_unprepare(dpi->engine_clk);
>   err_refcount:
>   	dpi->refcount--;

[...]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
  2022-05-30  8:38     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-02 11:38       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 11:38 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I think we should keep DPINTF_CH_SWAP?
BIT(1) = 2 so the shift should be:
dpi->conf->channel_swap_shift is 2 for MT8195-DP_INTF and 0 for
others.

BRs,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-06-02 11:38       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 11:38 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel, AngeloGioacchino Del Regno

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I think we should keep DPINTF_CH_SWAP?
BIT(1) = 2 so the shift should be:
dpi->conf->channel_swap_shift is 2 for MT8195-DP_INTF and 0 for
others.

BRs,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-06-02 11:38       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 11:38 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I think we should keep DPINTF_CH_SWAP?
BIT(1) = 2 so the shift should be:
dpi->conf->channel_swap_shift is 2 for MT8195-DP_INTF and 0 for
others.

BRs,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-06-02 11:38       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 11:38 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I think we should keep DPINTF_CH_SWAP?
BIT(1) = 2 so the shift should be:
dpi->conf->channel_swap_shift is 2 for MT8195-DP_INTF and 0 for
others.

BRs,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-06-02 11:38       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 11:38 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I think we should keep DPINTF_CH_SWAP?
BIT(1) = 2 so the shift should be:
dpi->conf->channel_swap_shift is 2 for MT8195-DP_INTF and 0 for
others.

BRs,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
  2022-05-30  8:38     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-02 12:19       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 12:19 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I have checked this with Jitao,
it's all shift 1 bit including mask and value.

I will modify like this:
#define DPINTF_CH_SWAP 1

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
val << dpi->conf-> channel_swap_shift,
CH_SWAP_MASK << dpi->conf->channel_swap_shift);


BR,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-06-02 12:19       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 12:19 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel, AngeloGioacchino Del Regno

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I have checked this with Jitao,
it's all shift 1 bit including mask and value.

I will modify like this:
#define DPINTF_CH_SWAP 1

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
val << dpi->conf-> channel_swap_shift,
CH_SWAP_MASK << dpi->conf->channel_swap_shift);


BR,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-06-02 12:19       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 12:19 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I have checked this with Jitao,
it's all shift 1 bit including mask and value.

I will modify like this:
#define DPINTF_CH_SWAP 1

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
val << dpi->conf-> channel_swap_shift,
CH_SWAP_MASK << dpi->conf->channel_swap_shift);


BR,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-06-02 12:19       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 12:19 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I have checked this with Jitao,
it's all shift 1 bit including mask and value.

I will modify like this:
#define DPINTF_CH_SWAP 1

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
val << dpi->conf-> channel_swap_shift,
CH_SWAP_MASK << dpi->conf->channel_swap_shift);


BR,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
@ 2022-06-02 12:19       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-02 12:19 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 16:38 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Add flexibility by moving the swap shift value to SoC specific
> > config
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 6eeda222a973..6d4d8c6ec47d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> >  	u32 dimension_mask;
> >  	/* HSIZE and VSIZE mask (no shift) */
> >  	u32 hvsize_mask;
> > +	u32 channel_swap_shift;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct
> > mtk_dpi *dpi,
> >  		break;
> >  	}
> >  
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > CH_SWAP_MASK);
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > > channel_swap_shift,
> > 
> > +		     CH_SWAP_MASK);
> > From the definiton:
> 
>  #define CH_SWAP				0
> +#define DPINTF_CH_SWAP			BIT(1)
>  #define CH_SWAP_MASK			(0x7 << 0)
> +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> 
> This statement should be:
> 
> mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf-
> > channel_swap_shift, CH_SWAP_MASK << dpi->conf->channel_swap_shift);
> 
> dpi->conf->channel_swap_shift is 1 for MT8195-DP_INTF and 0 for
> others.
> And drop the definition of DPINTF_CH_SWAP and DPINTF_CH_SWAP_MASK,
> 
> Regards,
> CK
> 

Hello CK,

I have checked this with Jitao,
it's all shift 1 bit including mask and value.

I will modify like this:
#define DPINTF_CH_SWAP 1

mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
val << dpi->conf-> channel_swap_shift,
CH_SWAP_MASK << dpi->conf->channel_swap_shift);


BR,
Bo-Chen
> 
> >  }
> >  
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool
> > enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.swap_input_support = true,
> >  	.dimension_mask = HPW_MASK,
> >  	.hvsize_mask = HSIZE_MASK,
> > +	.channel_swap_shift = CH_SWAP,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-02 13:20     ` Rob Herring
  -1 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-06-02 13:20 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, May 23, 2022 at 12:47:35PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>  1 file changed, 99 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

The example has warnings. Run 'make dt_binding_check' before submitting.

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-02 13:20     ` Rob Herring
  0 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-06-02 13:20 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, May 23, 2022 at 12:47:35PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>  1 file changed, 99 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

The example has warnings. Run 'make dt_binding_check' before submitting.

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-02 13:20     ` Rob Herring
  0 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-06-02 13:20 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: linux-fbdev, devicetree, David Airlie, dri-devel,
	Krzysztof Kozlowski, linux-phy, Helge Deller,
	Kishon Vijay Abraham I, Chunfeng Yun, Chun-Kuang Hu, Jitao shi,
	Thomas Zimmermann, Markus Schneider-Pargmann, linux-mediatek,
	Matthias Brugger, linux-arm-kernel, linux-kernel, Vinod Koul

On Mon, May 23, 2022 at 12:47:35PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>  1 file changed, 99 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

The example has warnings. Run 'make dt_binding_check' before submitting.

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-02 13:20     ` Rob Herring
  0 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-06-02 13:20 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, May 23, 2022 at 12:47:35PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>  1 file changed, 99 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

The example has warnings. Run 'make dt_binding_check' before submitting.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-02 13:20     ` Rob Herring
  0 siblings, 0 replies; 450+ messages in thread
From: Rob Herring @ 2022-06-02 13:20 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, May 23, 2022 at 12:47:35PM +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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 <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  .../display/mediatek/mediatek,dp.yaml         | 99 +++++++++++++++++++
>  1 file changed, 99 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

The example has warnings. Run 'make dt_binding_check' before submitting.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
  2022-05-25 11:55     ` AngeloGioacchino Del Regno
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  2:31       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:31 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 13:55 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13
> > ++++++++-----
> >   1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >   
> >   maintainers:
> >     - CK Hu <ck.hu@mediatek.com>
> >     - Jitao shi <jitao.shi@mediatek.com>
> >   
> >   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 DPINTF 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
> > @@ -35,12 +36,14 @@ properties:
> >         - description: Pixel Clock
> >         - description: Engine Clock
> >         - description: DPI PLL
> > +      - description: Optional CK CG Clock
> >   
> >     clock-names:
> >       items:
> >         - const: pixel
> >         - const: engine
> >         - const: pll
> > +      - const: ck_cg
> 
> This is my understanding on how the DisplayPort Interface clocks work
> on 8195:
> 
> The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
> "pll" is for TVD PLL divider selection
> "pixel" is the gate for the pixel clock to the connected display.
> 
> "ck_cg" is useless, as that's the parent of "pixel" (and will always
> be)... for
> example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
> CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its
> parent, hence
> enabling the first will enable the latter.
> 
> That said... you can most probably avoid adding the ck_cg clock, as
> if you try
> to turn that off while it's in use by its children, you'll be only
> decrementing
> a refcount, but no "real action" will ever take place.
> 
> 
> Regards,
> Angelo

Hello Chunfeng and Angelo,

ck_cg is a clock gate, and I try to remove it from drivers but it's
failed to enable dp_intf.

the block diagram is:
1. 26M->CLK_APMIXED_TVDPLL1(pll)->CLK_TOP_EDP(pixel)-
>CLK_VDO0_DP_INTF0_DP_INTF(ck_cg)->dp_intf

2. VDOSYS clock->CLK_VDO0_DP_INTF0(engine)->dp_intf

"engine" and "ck_cg" are all clock gates which control the clock source
input to dp_intf.

Maybe we just need to rename it?
If so, what name do you think we should modify?

BRs,
Bo-Chen

> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-06-07  2:31       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:31 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-05-25 at 13:55 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13
> > ++++++++-----
> >   1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >   
> >   maintainers:
> >     - CK Hu <ck.hu@mediatek.com>
> >     - Jitao shi <jitao.shi@mediatek.com>
> >   
> >   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 DPINTF 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
> > @@ -35,12 +36,14 @@ properties:
> >         - description: Pixel Clock
> >         - description: Engine Clock
> >         - description: DPI PLL
> > +      - description: Optional CK CG Clock
> >   
> >     clock-names:
> >       items:
> >         - const: pixel
> >         - const: engine
> >         - const: pll
> > +      - const: ck_cg
> 
> This is my understanding on how the DisplayPort Interface clocks work
> on 8195:
> 
> The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
> "pll" is for TVD PLL divider selection
> "pixel" is the gate for the pixel clock to the connected display.
> 
> "ck_cg" is useless, as that's the parent of "pixel" (and will always
> be)... for
> example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
> CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its
> parent, hence
> enabling the first will enable the latter.
> 
> That said... you can most probably avoid adding the ck_cg clock, as
> if you try
> to turn that off while it's in use by its children, you'll be only
> decrementing
> a refcount, but no "real action" will ever take place.
> 
> 
> Regards,
> Angelo

Hello Chunfeng and Angelo,

ck_cg is a clock gate, and I try to remove it from drivers but it's
failed to enable dp_intf.

the block diagram is:
1. 26M->CLK_APMIXED_TVDPLL1(pll)->CLK_TOP_EDP(pixel)-
>CLK_VDO0_DP_INTF0_DP_INTF(ck_cg)->dp_intf

2. VDOSYS clock->CLK_VDO0_DP_INTF0(engine)->dp_intf

"engine" and "ck_cg" are all clock gates which control the clock source
input to dp_intf.

Maybe we just need to rename it?
If so, what name do you think we should modify?

BRs,
Bo-Chen

> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-06-07  2:31       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:31 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 13:55 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13
> > ++++++++-----
> >   1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >   
> >   maintainers:
> >     - CK Hu <ck.hu@mediatek.com>
> >     - Jitao shi <jitao.shi@mediatek.com>
> >   
> >   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 DPINTF 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
> > @@ -35,12 +36,14 @@ properties:
> >         - description: Pixel Clock
> >         - description: Engine Clock
> >         - description: DPI PLL
> > +      - description: Optional CK CG Clock
> >   
> >     clock-names:
> >       items:
> >         - const: pixel
> >         - const: engine
> >         - const: pll
> > +      - const: ck_cg
> 
> This is my understanding on how the DisplayPort Interface clocks work
> on 8195:
> 
> The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
> "pll" is for TVD PLL divider selection
> "pixel" is the gate for the pixel clock to the connected display.
> 
> "ck_cg" is useless, as that's the parent of "pixel" (and will always
> be)... for
> example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
> CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its
> parent, hence
> enabling the first will enable the latter.
> 
> That said... you can most probably avoid adding the ck_cg clock, as
> if you try
> to turn that off while it's in use by its children, you'll be only
> decrementing
> a refcount, but no "real action" will ever take place.
> 
> 
> Regards,
> Angelo

Hello Chunfeng and Angelo,

ck_cg is a clock gate, and I try to remove it from drivers but it's
failed to enable dp_intf.

the block diagram is:
1. 26M->CLK_APMIXED_TVDPLL1(pll)->CLK_TOP_EDP(pixel)-
>CLK_VDO0_DP_INTF0_DP_INTF(ck_cg)->dp_intf

2. VDOSYS clock->CLK_VDO0_DP_INTF0(engine)->dp_intf

"engine" and "ck_cg" are all clock gates which control the clock source
input to dp_intf.

Maybe we just need to rename it?
If so, what name do you think we should modify?

BRs,
Bo-Chen

> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-06-07  2:31       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:31 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 13:55 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13
> > ++++++++-----
> >   1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >   
> >   maintainers:
> >     - CK Hu <ck.hu@mediatek.com>
> >     - Jitao shi <jitao.shi@mediatek.com>
> >   
> >   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 DPINTF 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
> > @@ -35,12 +36,14 @@ properties:
> >         - description: Pixel Clock
> >         - description: Engine Clock
> >         - description: DPI PLL
> > +      - description: Optional CK CG Clock
> >   
> >     clock-names:
> >       items:
> >         - const: pixel
> >         - const: engine
> >         - const: pll
> > +      - const: ck_cg
> 
> This is my understanding on how the DisplayPort Interface clocks work
> on 8195:
> 
> The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
> "pll" is for TVD PLL divider selection
> "pixel" is the gate for the pixel clock to the connected display.
> 
> "ck_cg" is useless, as that's the parent of "pixel" (and will always
> be)... for
> example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
> CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its
> parent, hence
> enabling the first will enable the latter.
> 
> That said... you can most probably avoid adding the ck_cg clock, as
> if you try
> to turn that off while it's in use by its children, you'll be only
> decrementing
> a refcount, but no "real action" will ever take place.
> 
> 
> Regards,
> Angelo

Hello Chunfeng and Angelo,

ck_cg is a clock gate, and I try to remove it from drivers but it's
failed to enable dp_intf.

the block diagram is:
1. 26M->CLK_APMIXED_TVDPLL1(pll)->CLK_TOP_EDP(pixel)-
>CLK_VDO0_DP_INTF0_DP_INTF(ck_cg)->dp_intf

2. VDOSYS clock->CLK_VDO0_DP_INTF0(engine)->dp_intf

"engine" and "ck_cg" are all clock gates which control the clock source
input to dp_intf.

Maybe we just need to rename it?
If so, what name do you think we should modify?

BRs,
Bo-Chen

> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-06-07  2:31       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:31 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 13:55 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../bindings/display/mediatek/mediatek,dpi.yaml     | 13
> > ++++++++-----
> >   1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >   
> >   maintainers:
> >     - CK Hu <ck.hu@mediatek.com>
> >     - Jitao shi <jitao.shi@mediatek.com>
> >   
> >   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 DPINTF 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
> > @@ -35,12 +36,14 @@ properties:
> >         - description: Pixel Clock
> >         - description: Engine Clock
> >         - description: DPI PLL
> > +      - description: Optional CK CG Clock
> >   
> >     clock-names:
> >       items:
> >         - const: pixel
> >         - const: engine
> >         - const: pll
> > +      - const: ck_cg
> 
> This is my understanding on how the DisplayPort Interface clocks work
> on 8195:
> 
> The "engine" clock is for the *VPP Engine's DisplayPort ip/block*,
> "pll" is for TVD PLL divider selection
> "pixel" is the gate for the pixel clock to the connected display.
> 
> "ck_cg" is useless, as that's the parent of "pixel" (and will always
> be)... for
> example, on mt8195... check clk/mediatek/clk-mt8195-vdo0.c - the
> CLK_VDO0_DP_INTF0_DP_INTF clock already has CLK_TOP_EDP as its
> parent, hence
> enabling the first will enable the latter.
> 
> That said... you can most probably avoid adding the ck_cg clock, as
> if you try
> to turn that off while it's in use by its children, you'll be only
> decrementing
> a refcount, but no "real action" will ever take place.
> 
> 
> Regards,
> Angelo

Hello Chunfeng and Angelo,

ck_cg is a clock gate, and I try to remove it from drivers but it's
failed to enable dp_intf.

the block diagram is:
1. 26M->CLK_APMIXED_TVDPLL1(pll)->CLK_TOP_EDP(pixel)-
>CLK_VDO0_DP_INTF0_DP_INTF(ck_cg)->dp_intf

2. VDOSYS clock->CLK_VDO0_DP_INTF0(engine)->dp_intf

"engine" and "ck_cg" are all clock gates which control the clock source
input to dp_intf.

Maybe we just need to rename it?
If so, what name do you think we should modify?

BRs,
Bo-Chen

> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
  2022-05-25 12:49     ` Maxime Ripard
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  2:35       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:35 UTC (permalink / raw)
  To: Maxime Ripard, Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Wed, 2022-05-25 at 14:49 +0200, Maxime Ripard wrote:
> Hi,
> 
> On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-
> > ----
> >  1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >  
> >  maintainers:
> >    - CK Hu <ck.hu@mediatek.com>
> >    - Jitao shi <jitao.shi@mediatek.com>
> >  
> >  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 DPINTF 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
> 
> Weren't you supposed to change it to have a separator between dp and
> intf?
> 
> If it's no longer in your plans, the second patch should have
> s/dp_intf/dpintf/
> 
> Maxime

Hello Maxime,

Thank for your review.
I will do this in next version.

BRs,
Bo-Chen

> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-06-07  2:35       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:35 UTC (permalink / raw)
  To: Maxime Ripard, Guillaume Ranquet
  Cc: linux-fbdev, devicetree, David Airlie, dri-devel,
	Krzysztof Kozlowski, linux-phy, Helge Deller,
	Kishon Vijay Abraham I, Chun-Kuang Hu, Jitao shi,
	Thomas Zimmermann, Markus Schneider-Pargmann, Chunfeng Yun,
	Rob Herring, linux-mediatek, Matthias Brugger, linux-arm-kernel,
	linux-kernel, Vinod Koul

On Wed, 2022-05-25 at 14:49 +0200, Maxime Ripard wrote:
> Hi,
> 
> On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-
> > ----
> >  1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >  
> >  maintainers:
> >    - CK Hu <ck.hu@mediatek.com>
> >    - Jitao shi <jitao.shi@mediatek.com>
> >  
> >  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 DPINTF 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
> 
> Weren't you supposed to change it to have a separator between dp and
> intf?
> 
> If it's no longer in your plans, the second patch should have
> s/dp_intf/dpintf/
> 
> Maxime

Hello Maxime,

Thank for your review.
I will do this in next version.

BRs,
Bo-Chen

> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-06-07  2:35       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:35 UTC (permalink / raw)
  To: Maxime Ripard, Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Wed, 2022-05-25 at 14:49 +0200, Maxime Ripard wrote:
> Hi,
> 
> On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-
> > ----
> >  1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >  
> >  maintainers:
> >    - CK Hu <ck.hu@mediatek.com>
> >    - Jitao shi <jitao.shi@mediatek.com>
> >  
> >  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 DPINTF 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
> 
> Weren't you supposed to change it to have a separator between dp and
> intf?
> 
> If it's no longer in your plans, the second patch should have
> s/dp_intf/dpintf/
> 
> Maxime

Hello Maxime,

Thank for your review.
I will do this in next version.

BRs,
Bo-Chen

> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-06-07  2:35       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:35 UTC (permalink / raw)
  To: Maxime Ripard, Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Wed, 2022-05-25 at 14:49 +0200, Maxime Ripard wrote:
> Hi,
> 
> On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-
> > ----
> >  1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >  
> >  maintainers:
> >    - CK Hu <ck.hu@mediatek.com>
> >    - Jitao shi <jitao.shi@mediatek.com>
> >  
> >  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 DPINTF 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
> 
> Weren't you supposed to change it to have a separator between dp and
> intf?
> 
> If it's no longer in your plans, the second patch should have
> s/dp_intf/dpintf/
> 
> Maxime

Hello Maxime,

Thank for your review.
I will do this in next version.

BRs,
Bo-Chen

> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible
@ 2022-06-07  2:35       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:35 UTC (permalink / raw)
  To: Maxime Ripard, Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi, Markus Schneider-Pargmann, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Wed, 2022-05-25 at 14:49 +0200, Maxime Ripard wrote:
> Hi,
> 
> On Mon, May 23, 2022 at 12:47:34PM +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > DPINTF is similar to DPI but does not have the exact same feature
> > set
> > or register layouts.
> > 
> > DPINTF 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../bindings/display/mediatek/mediatek,dpi.yaml     | 13 ++++++++-
> > ----
> >  1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > index dd2896a40ff0..6d9f6c11806e 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.y
> > aml
> > @@ -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/DPINTF Controller
> >  
> >  maintainers:
> >    - CK Hu <ck.hu@mediatek.com>
> >    - Jitao shi <jitao.shi@mediatek.com>
> >  
> >  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 DPINTF 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
> 
> Weren't you supposed to change it to have a separator between dp and
> intf?
> 
> If it's no longer in your plans, the second patch should have
> s/dp_intf/dpintf/
> 
> Maxime

Hello Maxime,

Thank for your review.
I will do this in next version.

BRs,
Bo-Chen

> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
  2022-05-23 10:57     ` Matthias Brugger
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  2:44       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:44 UTC (permalink / raw)
  To: Matthias Brugger, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:57 +0200, Matthias Brugger wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > 
> 
> We need a commit message here.
> 

Hello Matthias,

ok, I will add commit message in next version.

Thanks.

BRs,
Bo-Chen

> > ---
> >  include/drm/drm_edid.h | 12 +++++++++---
> >  1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >  
> >  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> > << 8))
> >  
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >  struct cea_sad {
> >         u8 format;
> > -       u8 channels; /* max number of channels - 1 */
> > +       u8 channels;
> >         u8 freq;
> > -       u8 byte2; /* meaning depends on format */
> > +       u8 byte2;
> >  };
> >  
> >  struct drm_encoder;
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-06-07  2:44       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:44 UTC (permalink / raw)
  To: Matthias Brugger, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

On Mon, 2022-05-23 at 12:57 +0200, Matthias Brugger wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > 
> 
> We need a commit message here.
> 

Hello Matthias,

ok, I will add commit message in next version.

Thanks.

BRs,
Bo-Chen

> > ---
> >  include/drm/drm_edid.h | 12 +++++++++---
> >  1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >  
> >  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> > << 8))
> >  
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >  struct cea_sad {
> >         u8 format;
> > -       u8 channels; /* max number of channels - 1 */
> > +       u8 channels;
> >         u8 freq;
> > -       u8 byte2; /* meaning depends on format */
> > +       u8 byte2;
> >  };
> >  
> >  struct drm_encoder;
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-06-07  2:44       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:44 UTC (permalink / raw)
  To: Matthias Brugger, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:57 +0200, Matthias Brugger wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > 
> 
> We need a commit message here.
> 

Hello Matthias,

ok, I will add commit message in next version.

Thanks.

BRs,
Bo-Chen

> > ---
> >  include/drm/drm_edid.h | 12 +++++++++---
> >  1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >  
> >  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> > << 8))
> >  
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >  struct cea_sad {
> >         u8 format;
> > -       u8 channels; /* max number of channels - 1 */
> > +       u8 channels;
> >         u8 freq;
> > -       u8 byte2; /* meaning depends on format */
> > +       u8 byte2;
> >  };
> >  
> >  struct drm_encoder;
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-06-07  2:44       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:44 UTC (permalink / raw)
  To: Matthias Brugger, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:57 +0200, Matthias Brugger wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > 
> 
> We need a commit message here.
> 

Hello Matthias,

ok, I will add commit message in next version.

Thanks.

BRs,
Bo-Chen

> > ---
> >  include/drm/drm_edid.h | 12 +++++++++---
> >  1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >  
> >  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> > << 8))
> >  
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >  struct cea_sad {
> >         u8 format;
> > -       u8 channels; /* max number of channels - 1 */
> > +       u8 channels;
> >         u8 freq;
> > -       u8 byte2; /* meaning depends on format */
> > +       u8 byte2;
> >  };
> >  
> >  struct drm_encoder;
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-06-07  2:44       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:44 UTC (permalink / raw)
  To: Matthias Brugger, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, CK Hu, Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Mon, 2022-05-23 at 12:57 +0200, Matthias Brugger wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > 
> 
> We need a commit message here.
> 

Hello Matthias,

ok, I will add commit message in next version.

Thanks.

BRs,
Bo-Chen

> > ---
> >  include/drm/drm_edid.h | 12 +++++++++---
> >  1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >  
> >  #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1]
> > << 8))
> >  
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >  struct cea_sad {
> >         u8 format;
> > -       u8 channels; /* max number of channels - 1 */
> > +       u8 channels;
> >         u8 freq;
> > -       u8 byte2; /* meaning depends on format */
> > +       u8 byte2;
> >  };
> >  
> >  struct drm_encoder;
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
  2022-05-25 12:01     ` AngeloGioacchino Del Regno
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  2:45       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:45 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:01 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   include/drm/drm_edid.h | 12 +++++++++---
> >   1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >   
> >   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)-
> > >prod_code[1] << 8))
> >   
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> 
> Perhaps....
> 
> * struct cea_sad - CEA Short Audio Descriptor
> 
> ...but that's relative to personal liking and nothing else, it's also
> fine as
> it is, if you like it more as it is. The ball is yours :-P
> 
> Regardless of any choice about changing the description or not:
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> 
> Cheers,
> Angelo
> 

Hello Angelo,

ok, I will do this in next version.

BRs,
Bo-Chen

> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >   struct cea_sad {
> >   	u8 format;
> > -	u8 channels; /* max number of channels - 1 */
> > +	u8 channels;
> >   	u8 freq;
> > -	u8 byte2; /* meaning depends on format */
> > +	u8 byte2;
> >   };
> >   
> >   struct drm_encoder;
> 
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-06-07  2:45       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:45 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel

On Wed, 2022-05-25 at 14:01 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   include/drm/drm_edid.h | 12 +++++++++---
> >   1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >   
> >   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)-
> > >prod_code[1] << 8))
> >   
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> 
> Perhaps....
> 
> * struct cea_sad - CEA Short Audio Descriptor
> 
> ...but that's relative to personal liking and nothing else, it's also
> fine as
> it is, if you like it more as it is. The ball is yours :-P
> 
> Regardless of any choice about changing the description or not:
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> 
> Cheers,
> Angelo
> 

Hello Angelo,

ok, I will do this in next version.

BRs,
Bo-Chen

> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >   struct cea_sad {
> >   	u8 format;
> > -	u8 channels; /* max number of channels - 1 */
> > +	u8 channels;
> >   	u8 freq;
> > -	u8 byte2; /* meaning depends on format */
> > +	u8 byte2;
> >   };
> >   
> >   struct drm_encoder;
> 
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-06-07  2:45       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:45 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:01 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   include/drm/drm_edid.h | 12 +++++++++---
> >   1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >   
> >   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)-
> > >prod_code[1] << 8))
> >   
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> 
> Perhaps....
> 
> * struct cea_sad - CEA Short Audio Descriptor
> 
> ...but that's relative to personal liking and nothing else, it's also
> fine as
> it is, if you like it more as it is. The ball is yours :-P
> 
> Regardless of any choice about changing the description or not:
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> 
> Cheers,
> Angelo
> 

Hello Angelo,

ok, I will do this in next version.

BRs,
Bo-Chen

> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >   struct cea_sad {
> >   	u8 format;
> > -	u8 channels; /* max number of channels - 1 */
> > +	u8 channels;
> >   	u8 freq;
> > -	u8 byte2; /* meaning depends on format */
> > +	u8 byte2;
> >   };
> >   
> >   struct drm_encoder;
> 
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-06-07  2:45       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:45 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:01 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   include/drm/drm_edid.h | 12 +++++++++---
> >   1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >   
> >   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)-
> > >prod_code[1] << 8))
> >   
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> 
> Perhaps....
> 
> * struct cea_sad - CEA Short Audio Descriptor
> 
> ...but that's relative to personal liking and nothing else, it's also
> fine as
> it is, if you like it more as it is. The ball is yours :-P
> 
> Regardless of any choice about changing the description or not:
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> 
> Cheers,
> Angelo
> 

Hello Angelo,

ok, I will do this in next version.

BRs,
Bo-Chen

> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >   struct cea_sad {
> >   	u8 format;
> > -	u8 channels; /* max number of channels - 1 */
> > +	u8 channels;
> >   	u8 freq;
> > -	u8 byte2; /* meaning depends on format */
> > +	u8 byte2;
> >   };
> >   
> >   struct drm_encoder;
> 
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
@ 2022-06-07  2:45       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:45 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:01 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   include/drm/drm_edid.h | 12 +++++++++---
> >   1 file changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 144c495b99c4..37c420423625 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -359,12 +359,18 @@ struct edid {
> >   
> >   #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)-
> > >prod_code[1] << 8))
> >   
> > -/* Short Audio Descriptor */
> > +/**
> > + * struct cea_sad - Short Audio Descriptor.
> 
> Perhaps....
> 
> * struct cea_sad - CEA Short Audio Descriptor
> 
> ...but that's relative to personal liking and nothing else, it's also
> fine as
> it is, if you like it more as it is. The ball is yours :-P
> 
> Regardless of any choice about changing the description or not:
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> 
> Cheers,
> Angelo
> 

Hello Angelo,

ok, I will do this in next version.

BRs,
Bo-Chen

> > + * @format: See HDMI_AUDIO_CODING_TYPE_*.
> > + * @channels: max number of channels - 1.
> > + * @freq: See CEA_SAD_FREQ_*.
> > + * @byte2: meaning depends on format.
> > + */
> >   struct cea_sad {
> >   	u8 format;
> > -	u8 channels; /* max number of channels - 1 */
> > +	u8 channels;
> >   	u8 freq;
> > -	u8 byte2; /* meaning depends on format */
> > +	u8 byte2;
> >   };
> >   
> >   struct drm_encoder;
> 
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
  2022-05-30  7:44     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  2:54       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 15:44 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without CK/DE pol support
> 
> It seems that DP_INTF has no CK/DE pol function. If so, could you
> explain why DP_INTF has this difference with DPI?
> 
> Regards,
> CK
> 

Hello CK,

Dp_intf does not support CK/DE polarity because the polarity
information is not used for eDP and DP while dp_intf is only for eDP
and DP.

I will add this in commit message in next version.

BRs,
Bo-Chen

> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
> >  1 file changed, 17 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4746eb342567..545a1337cc89 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
> >  	bool edge_sel_en;
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> > +	bool is_ck_de_pol;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> > *dpi,
> >  			       struct mtk_dpi_polarities *dpi_pol)
> >  {
> >  	unsigned int pol;
> > +	unsigned int mask;
> >  
> > -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> > > 
> > 
> > -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> > > 
> > 
> > -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> > +	mask = HSYNC_POL | VSYNC_POL;
> > +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> >  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > VSYNC_POL);
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> > -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> > +	if (dpi->conf->is_ck_de_pol) {
> > +		mask |= CK_POL | DE_POL;
> > +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : CK_POL) |
> > +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : DE_POL);
> > +	}
> > +
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
> >  }
> >  
> >  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> > @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.max_clock_khz = 300000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.max_clock_khz = 100000,
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-06-07  2:54       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel, AngeloGioacchino Del Regno

On Mon, 2022-05-30 at 15:44 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without CK/DE pol support
> 
> It seems that DP_INTF has no CK/DE pol function. If so, could you
> explain why DP_INTF has this difference with DPI?
> 
> Regards,
> CK
> 

Hello CK,

Dp_intf does not support CK/DE polarity because the polarity
information is not used for eDP and DP while dp_intf is only for eDP
and DP.

I will add this in commit message in next version.

BRs,
Bo-Chen

> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
> >  1 file changed, 17 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4746eb342567..545a1337cc89 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
> >  	bool edge_sel_en;
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> > +	bool is_ck_de_pol;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> > *dpi,
> >  			       struct mtk_dpi_polarities *dpi_pol)
> >  {
> >  	unsigned int pol;
> > +	unsigned int mask;
> >  
> > -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> > > 
> > 
> > -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> > > 
> > 
> > -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> > +	mask = HSYNC_POL | VSYNC_POL;
> > +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> >  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > VSYNC_POL);
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> > -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> > +	if (dpi->conf->is_ck_de_pol) {
> > +		mask |= CK_POL | DE_POL;
> > +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : CK_POL) |
> > +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : DE_POL);
> > +	}
> > +
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
> >  }
> >  
> >  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> > @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.max_clock_khz = 300000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.max_clock_khz = 100000,
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-06-07  2:54       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 15:44 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without CK/DE pol support
> 
> It seems that DP_INTF has no CK/DE pol function. If so, could you
> explain why DP_INTF has this difference with DPI?
> 
> Regards,
> CK
> 

Hello CK,

Dp_intf does not support CK/DE polarity because the polarity
information is not used for eDP and DP while dp_intf is only for eDP
and DP.

I will add this in commit message in next version.

BRs,
Bo-Chen

> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
> >  1 file changed, 17 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4746eb342567..545a1337cc89 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
> >  	bool edge_sel_en;
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> > +	bool is_ck_de_pol;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> > *dpi,
> >  			       struct mtk_dpi_polarities *dpi_pol)
> >  {
> >  	unsigned int pol;
> > +	unsigned int mask;
> >  
> > -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> > > 
> > 
> > -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> > > 
> > 
> > -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> > +	mask = HSYNC_POL | VSYNC_POL;
> > +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> >  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > VSYNC_POL);
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> > -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> > +	if (dpi->conf->is_ck_de_pol) {
> > +		mask |= CK_POL | DE_POL;
> > +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : CK_POL) |
> > +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : DE_POL);
> > +	}
> > +
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
> >  }
> >  
> >  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> > @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.max_clock_khz = 300000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.max_clock_khz = 100000,
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-06-07  2:54       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 15:44 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without CK/DE pol support
> 
> It seems that DP_INTF has no CK/DE pol function. If so, could you
> explain why DP_INTF has this difference with DPI?
> 
> Regards,
> CK
> 

Hello CK,

Dp_intf does not support CK/DE polarity because the polarity
information is not used for eDP and DP while dp_intf is only for eDP
and DP.

I will add this in commit message in next version.

BRs,
Bo-Chen

> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
> >  1 file changed, 17 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4746eb342567..545a1337cc89 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
> >  	bool edge_sel_en;
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> > +	bool is_ck_de_pol;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> > *dpi,
> >  			       struct mtk_dpi_polarities *dpi_pol)
> >  {
> >  	unsigned int pol;
> > +	unsigned int mask;
> >  
> > -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> > > 
> > 
> > -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> > > 
> > 
> > -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> > +	mask = HSYNC_POL | VSYNC_POL;
> > +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> >  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > VSYNC_POL);
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> > -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> > +	if (dpi->conf->is_ck_de_pol) {
> > +		mask |= CK_POL | DE_POL;
> > +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : CK_POL) |
> > +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : DE_POL);
> > +	}
> > +
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
> >  }
> >  
> >  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> > @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.max_clock_khz = 300000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.max_clock_khz = 100000,
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in SoC config
@ 2022-06-07  2:54       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  2:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 15:44 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without CK/DE pol support
> 
> It seems that DP_INTF has no CK/DE pol function. If so, could you
> explain why DP_INTF has this difference with DPI?
> 
> Regards,
> CK
> 

Hello CK,

Dp_intf does not support CK/DE polarity because the polarity
information is not used for eDP and DP while dp_intf is only for eDP
and DP.

I will add this in commit message in next version.

BRs,
Bo-Chen

> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +++++++++++++++++-----
> >  1 file changed, 17 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4746eb342567..545a1337cc89 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
> >  	bool edge_sel_en;
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> > +	bool is_ck_de_pol;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi
> > *dpi,
> >  			       struct mtk_dpi_polarities *dpi_pol)
> >  {
> >  	unsigned int pol;
> > +	unsigned int mask;
> >  
> > -	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL)
> > > 
> > 
> > -	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL)
> > > 
> > 
> > -	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> > +	mask = HSYNC_POL | VSYNC_POL;
> > +	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > HSYNC_POL) |
> >  	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 :
> > VSYNC_POL);
> > -	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> > -		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> > +	if (dpi->conf->is_ck_de_pol) {
> > +		mask |= CK_POL | DE_POL;
> > +		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : CK_POL) |
> > +		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> > +			0 : DE_POL);
> > +	}
> > +
> > +	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
> >  }
> >  
> >  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> > @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.max_clock_khz = 300000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.max_clock_khz = 100000,
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.max_clock_khz = 150000,
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +	.is_ck_de_pol = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
  2022-05-25 12:32     ` AngeloGioacchino Del Regno
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  3:10       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  3:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:32 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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.
> > 
> > Also constify the frame parameter in hdmi_audio_infoframe_check()
> > as
> > it is passed to hdmi_audio_infoframe_check_only() which expects a
> > const.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++---
> > -----
> >   include/drm/dp/drm_dp_helper.h |  2 +
> 
> this has been moved... again... this time it's
> include/drm/display/drm_dp_helper.h
> 

Hello Angelo,

yes, I will rebase on 5.19-rc1 and fix this in next version.

BRs,
Bo-Chen
> >   include/linux/hdmi.h           |  7 ++-
> >   3 files changed, 71 insertions(+), 20 deletions(-)
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-06-07  3:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  3:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:32 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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.
> > 
> > Also constify the frame parameter in hdmi_audio_infoframe_check()
> > as
> > it is passed to hdmi_audio_infoframe_check_only() which expects a
> > const.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++---
> > -----
> >   include/drm/dp/drm_dp_helper.h |  2 +
> 
> this has been moved... again... this time it's
> include/drm/display/drm_dp_helper.h
> 

Hello Angelo,

yes, I will rebase on 5.19-rc1 and fix this in next version.

BRs,
Bo-Chen
> >   include/linux/hdmi.h           |  7 ++-
> >   3 files changed, 71 insertions(+), 20 deletions(-)
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-06-07  3:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  3:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-05-25 at 14:32 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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.
> > 
> > Also constify the frame parameter in hdmi_audio_infoframe_check()
> > as
> > it is passed to hdmi_audio_infoframe_check_only() which expects a
> > const.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++---
> > -----
> >   include/drm/dp/drm_dp_helper.h |  2 +
> 
> this has been moved... again... this time it's
> include/drm/display/drm_dp_helper.h
> 

Hello Angelo,

yes, I will rebase on 5.19-rc1 and fix this in next version.

BRs,
Bo-Chen
> >   include/linux/hdmi.h           |  7 ++-
> >   3 files changed, 71 insertions(+), 20 deletions(-)
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-06-07  3:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  3:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:32 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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.
> > 
> > Also constify the frame parameter in hdmi_audio_infoframe_check()
> > as
> > it is passed to hdmi_audio_infoframe_check_only() which expects a
> > const.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++---
> > -----
> >   include/drm/dp/drm_dp_helper.h |  2 +
> 
> this has been moved... again... this time it's
> include/drm/display/drm_dp_helper.h
> 

Hello Angelo,

yes, I will rebase on 5.19-rc1 and fix this in next version.

BRs,
Bo-Chen
> >   include/linux/hdmi.h           |  7 ++-
> >   3 files changed, 71 insertions(+), 20 deletions(-)
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP
@ 2022-06-07  3:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07  3:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:32 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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.
> > 
> > Also constify the frame parameter in hdmi_audio_infoframe_check()
> > as
> > it is passed to hdmi_audio_infoframe_check_only() which expects a
> > const.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/video/hdmi.c           | 82 ++++++++++++++++++++++++++---
> > -----
> >   include/drm/dp/drm_dp_helper.h |  2 +
> 
> this has been moved... again... this time it's
> include/drm/display/drm_dp_helper.h
> 

Hello Angelo,

yes, I will rebase on 5.19-rc1 and fix this in next version.

BRs,
Bo-Chen
> >   include/linux/hdmi.h           |  7 ++-
> >   3 files changed, 71 insertions(+), 20 deletions(-)
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  6:21     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:21 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)

event is always > 0, isn't it?

> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);

I think this ISR would come once. If bridge has not attached, the drm
core would lost this event. Maybe you should enable eDP hardware after
bridge attached or send this event when attached.

> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {

Executing this thread imply cable_state_change = true, so drop
cable_state_change.

> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {

I do not like two variable to present one thing. If

mtk_dp->train_info.cable_plugged_in = false
and
mtk_dp_plug_state(mtk_dp) = ture

What does this mean? I think this mean 'now' is connected because
cable_plugged_in is old information and mtk_dp_plug_state() is current
information.

But I would like to keep cable_plugged_in and drop mtk_dp_plug_state()
because cable_plugged_in would be changed in isr and it would be the
same as mtk_dp_plug_state().

Regards,
CK

> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  6:21     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:21 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)

event is always > 0, isn't it?

> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);

I think this ISR would come once. If bridge has not attached, the drm
core would lost this event. Maybe you should enable eDP hardware after
bridge attached or send this event when attached.

> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {

Executing this thread imply cable_state_change = true, so drop
cable_state_change.

> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {

I do not like two variable to present one thing. If

mtk_dp->train_info.cable_plugged_in = false
and
mtk_dp_plug_state(mtk_dp) = ture

What does this mean? I think this mean 'now' is connected because
cable_plugged_in is old information and mtk_dp_plug_state() is current
information.

But I would like to keep cable_plugged_in and drop mtk_dp_plug_state()
because cable_plugged_in would be changed in isr and it would be the
same as mtk_dp_plug_state().

Regards,
CK

> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  6:21     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:21 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)

event is always > 0, isn't it?

> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);

I think this ISR would come once. If bridge has not attached, the drm
core would lost this event. Maybe you should enable eDP hardware after
bridge attached or send this event when attached.

> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {

Executing this thread imply cable_state_change = true, so drop
cable_state_change.

> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {

I do not like two variable to present one thing. If

mtk_dp->train_info.cable_plugged_in = false
and
mtk_dp_plug_state(mtk_dp) = ture

What does this mean? I think this mean 'now' is connected because
cable_plugged_in is old information and mtk_dp_plug_state() is current
information.

But I would like to keep cable_plugged_in and drop mtk_dp_plug_state()
because cable_plugged_in would be changed in isr and it would be the
same as mtk_dp_plug_state().

Regards,
CK

> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  6:21     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:21 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)

event is always > 0, isn't it?

> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);

I think this ISR would come once. If bridge has not attached, the drm
core would lost this event. Maybe you should enable eDP hardware after
bridge attached or send this event when attached.

> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {

Executing this thread imply cable_state_change = true, so drop
cable_state_change.

> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {

I do not like two variable to present one thing. If

mtk_dp->train_info.cable_plugged_in = false
and
mtk_dp_plug_state(mtk_dp) = ture

What does this mean? I think this mean 'now' is connected because
cable_plugged_in is old information and mtk_dp_plug_state() is current
information.

But I would like to keep cable_plugged_in and drop mtk_dp_plug_state()
because cable_plugged_in would be changed in isr and it would be the
same as mtk_dp_plug_state().

Regards,
CK

> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  6:21     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:21 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)

event is always > 0, isn't it?

> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);

I think this ISR would come once. If bridge has not attached, the drm
core would lost this event. Maybe you should enable eDP hardware after
bridge attached or send this event when attached.

> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {

Executing this thread imply cable_state_change = true, so drop
cable_state_change.

> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {

I do not like two variable to present one thing. If

mtk_dp->train_info.cable_plugged_in = false
and
mtk_dp_plug_state(mtk_dp) = ture

What does this mean? I think this mean 'now' is connected because
cable_plugged_in is old information and mtk_dp_plug_state() is current
information.

But I would like to keep cable_plugged_in and drop mtk_dp_plug_state()
because cable_plugged_in would be changed in isr and it would be the
same as mtk_dp_plug_state().

Regards,
CK

> +			mtk_dp_video_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  6:44     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool training_done = false;
> +	short max_retry = 50;
> +	int ret = 0;
> +
> +	do {
> +		switch (mtk_dp->train_state) {
> +		case MTK_DP_TRAIN_STATE_STARTUP:

mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
though HPD ISR does not exist. Does this mean HPD ISR is redundant? If
HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
for init state.

> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKCAP;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> +				mtk_dp->train_info.check_cap_count = 0;
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKEDID;
> +			} else {
> +				mtk_dp->train_info.check_cap_count++;
> +
> +				if (mtk_dp->train_info.check_cap_count
> >
> +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> ) {
> +					mtk_dp-
> >train_info.check_cap_count = 0;
> +					mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +					ret = -ETIMEDOUT;
> +				}
> +			}
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING_PRE;

MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.

> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING:
> +			ret = mtk_dp_train_start(mtk_dp);
> +			if (ret == 0) {
> +				mtk_dp_video_mute(mtk_dp, true);
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_NORMAL;
> +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> >has_fec);
> +			} else if (ret != -EAGAIN) {
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +			}
> +			break;
> +		case MTK_DP_TRAIN_STATE_NORMAL:
> +			mtk_dp_state_handler(mtk_dp);
> +			training_done = true;
> +			break;
> +		case MTK_DP_TRAIN_STATE_DPIDLE:

When would this case happen?

Regards,
CK

> +			break;
> +		default:
> +			break;
> +		}
> +
> +		if (ret) {
> +			if (ret == -EAGAIN)
> +				continue;
> +			/*
> +			 * If we get any other error number, it doesn't
> +			 * make any sense to keep iterating.
> +			 */
> +			break;
> +		}
> +	} while (!training_done || --max_retry);
> +
> +	return ret;
> +}


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  6:44     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool training_done = false;
> +	short max_retry = 50;
> +	int ret = 0;
> +
> +	do {
> +		switch (mtk_dp->train_state) {
> +		case MTK_DP_TRAIN_STATE_STARTUP:

mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
though HPD ISR does not exist. Does this mean HPD ISR is redundant? If
HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
for init state.

> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKCAP;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> +				mtk_dp->train_info.check_cap_count = 0;
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKEDID;
> +			} else {
> +				mtk_dp->train_info.check_cap_count++;
> +
> +				if (mtk_dp->train_info.check_cap_count
> >
> +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> ) {
> +					mtk_dp-
> >train_info.check_cap_count = 0;
> +					mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +					ret = -ETIMEDOUT;
> +				}
> +			}
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING_PRE;

MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.

> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING:
> +			ret = mtk_dp_train_start(mtk_dp);
> +			if (ret == 0) {
> +				mtk_dp_video_mute(mtk_dp, true);
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_NORMAL;
> +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> >has_fec);
> +			} else if (ret != -EAGAIN) {
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +			}
> +			break;
> +		case MTK_DP_TRAIN_STATE_NORMAL:
> +			mtk_dp_state_handler(mtk_dp);
> +			training_done = true;
> +			break;
> +		case MTK_DP_TRAIN_STATE_DPIDLE:

When would this case happen?

Regards,
CK

> +			break;
> +		default:
> +			break;
> +		}
> +
> +		if (ret) {
> +			if (ret == -EAGAIN)
> +				continue;
> +			/*
> +			 * If we get any other error number, it doesn't
> +			 * make any sense to keep iterating.
> +			 */
> +			break;
> +		}
> +	} while (!training_done || --max_retry);
> +
> +	return ret;
> +}


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  6:44     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool training_done = false;
> +	short max_retry = 50;
> +	int ret = 0;
> +
> +	do {
> +		switch (mtk_dp->train_state) {
> +		case MTK_DP_TRAIN_STATE_STARTUP:

mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
though HPD ISR does not exist. Does this mean HPD ISR is redundant? If
HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
for init state.

> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKCAP;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> +				mtk_dp->train_info.check_cap_count = 0;
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKEDID;
> +			} else {
> +				mtk_dp->train_info.check_cap_count++;
> +
> +				if (mtk_dp->train_info.check_cap_count
> >
> +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> ) {
> +					mtk_dp-
> >train_info.check_cap_count = 0;
> +					mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +					ret = -ETIMEDOUT;
> +				}
> +			}
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING_PRE;

MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.

> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING:
> +			ret = mtk_dp_train_start(mtk_dp);
> +			if (ret == 0) {
> +				mtk_dp_video_mute(mtk_dp, true);
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_NORMAL;
> +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> >has_fec);
> +			} else if (ret != -EAGAIN) {
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +			}
> +			break;
> +		case MTK_DP_TRAIN_STATE_NORMAL:
> +			mtk_dp_state_handler(mtk_dp);
> +			training_done = true;
> +			break;
> +		case MTK_DP_TRAIN_STATE_DPIDLE:

When would this case happen?

Regards,
CK

> +			break;
> +		default:
> +			break;
> +		}
> +
> +		if (ret) {
> +			if (ret == -EAGAIN)
> +				continue;
> +			/*
> +			 * If we get any other error number, it doesn't
> +			 * make any sense to keep iterating.
> +			 */
> +			break;
> +		}
> +	} while (!training_done || --max_retry);
> +
> +	return ret;
> +}


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  6:44     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool training_done = false;
> +	short max_retry = 50;
> +	int ret = 0;
> +
> +	do {
> +		switch (mtk_dp->train_state) {
> +		case MTK_DP_TRAIN_STATE_STARTUP:

mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
though HPD ISR does not exist. Does this mean HPD ISR is redundant? If
HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
for init state.

> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKCAP;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> +				mtk_dp->train_info.check_cap_count = 0;
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKEDID;
> +			} else {
> +				mtk_dp->train_info.check_cap_count++;
> +
> +				if (mtk_dp->train_info.check_cap_count
> >
> +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> ) {
> +					mtk_dp-
> >train_info.check_cap_count = 0;
> +					mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +					ret = -ETIMEDOUT;
> +				}
> +			}
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING_PRE;

MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.

> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING:
> +			ret = mtk_dp_train_start(mtk_dp);
> +			if (ret == 0) {
> +				mtk_dp_video_mute(mtk_dp, true);
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_NORMAL;
> +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> >has_fec);
> +			} else if (ret != -EAGAIN) {
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +			}
> +			break;
> +		case MTK_DP_TRAIN_STATE_NORMAL:
> +			mtk_dp_state_handler(mtk_dp);
> +			training_done = true;
> +			break;
> +		case MTK_DP_TRAIN_STATE_DPIDLE:

When would this case happen?

Regards,
CK

> +			break;
> +		default:
> +			break;
> +		}
> +
> +		if (ret) {
> +			if (ret == -EAGAIN)
> +				continue;
> +			/*
> +			 * If we get any other error number, it doesn't
> +			 * make any sense to keep iterating.
> +			 */
> +			break;
> +		}
> +	} while (!training_done || --max_retry);
> +
> +	return ret;
> +}


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  6:44     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  6:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool training_done = false;
> +	short max_retry = 50;
> +	int ret = 0;
> +
> +	do {
> +		switch (mtk_dp->train_state) {
> +		case MTK_DP_TRAIN_STATE_STARTUP:

mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
though HPD ISR does not exist. Does this mean HPD ISR is redundant? If
HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
for init state.

> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKCAP;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> +				mtk_dp->train_info.check_cap_count = 0;
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKEDID;
> +			} else {
> +				mtk_dp->train_info.check_cap_count++;
> +
> +				if (mtk_dp->train_info.check_cap_count
> >
> +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> ) {
> +					mtk_dp-
> >train_info.check_cap_count = 0;
> +					mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +					ret = -ETIMEDOUT;
> +				}
> +			}
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING_PRE;

MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.

> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> +			mtk_dp_state_handler(mtk_dp);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_TRAINING;
> +			break;
> +
> +		case MTK_DP_TRAIN_STATE_TRAINING:
> +			ret = mtk_dp_train_start(mtk_dp);
> +			if (ret == 0) {
> +				mtk_dp_video_mute(mtk_dp, true);
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_NORMAL;
> +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> >has_fec);
> +			} else if (ret != -EAGAIN) {
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +			}
> +			break;
> +		case MTK_DP_TRAIN_STATE_NORMAL:
> +			mtk_dp_state_handler(mtk_dp);
> +			training_done = true;
> +			break;
> +		case MTK_DP_TRAIN_STATE_DPIDLE:

When would this case happen?

Regards,
CK

> +			break;
> +		default:
> +			break;
> +		}
> +
> +		if (ret) {
> +			if (ret == -EAGAIN)
> +				continue;
> +			/*
> +			 * If we get any other error number, it doesn't
> +			 * make any sense to keep iterating.
> +			 */
> +			break;
> +		}
> +	} while (!training_done || --max_retry);
> +
> +	return ret;
> +}


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  7:30     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> +				   struct drm_dp_aux_msg *msg)
> +{
> +	struct mtk_dp *mtk_dp;
> +	bool is_read;
> +	u8 request;
> +	size_t accessed_bytes = 0;
> +	int ret = 0;
> +
> +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> +
> +	if (!mtk_dp->train_info.cable_plugged_in ||
> +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;

Changing state here has no any effect, so drop this.

> +		return -EAGAIN;
> +	}
> +
> +	switch (msg->request) {
> +	case DP_AUX_I2C_MOT:
> +	case DP_AUX_I2C_WRITE:
> +	case DP_AUX_NATIVE_WRITE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> +		request = msg->request &
> ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> +		is_read = false;
> +		break;
> +	case DP_AUX_I2C_READ:
> +	case DP_AUX_NATIVE_READ:
> +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> +		request = msg->request;
> +		is_read = true;
> +		break;
> +	default:
> +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> +			msg->request);
> +		return -EINVAL;
> +	}
> +
> +	if (msg->size == 0) {
> +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> +					     msg->address +
> accessed_bytes,
> +					     msg->buffer +
> accessed_bytes, 0);
> +	} else {
> +		while (accessed_bytes < msg->size) {
> +			size_t to_access =
> +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> +				      msg->size - accessed_bytes);
> +
> +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> +						     is_read, request,
> +							 msg->address +
> accessed_bytes,
> +							 msg->buffer +
> accessed_bytes,
> +							 to_access);
> +
> +			if (ret) {
> +				drm_info(mtk_dp->drm_dev,
> +					 "Failed to do AUX transfer:
> %d\n", ret);
> +				break;
> +			}
> +			accessed_bytes += to_access;
> +		}
> +	}
> +
> +	if (ret) {
> +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> DP_AUX_I2C_REPLY_NACK;
> +		return ret;
> +	}
> +
> +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> +	return msg->size;
> +}


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  7:30     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> +				   struct drm_dp_aux_msg *msg)
> +{
> +	struct mtk_dp *mtk_dp;
> +	bool is_read;
> +	u8 request;
> +	size_t accessed_bytes = 0;
> +	int ret = 0;
> +
> +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> +
> +	if (!mtk_dp->train_info.cable_plugged_in ||
> +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;

Changing state here has no any effect, so drop this.

> +		return -EAGAIN;
> +	}
> +
> +	switch (msg->request) {
> +	case DP_AUX_I2C_MOT:
> +	case DP_AUX_I2C_WRITE:
> +	case DP_AUX_NATIVE_WRITE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> +		request = msg->request &
> ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> +		is_read = false;
> +		break;
> +	case DP_AUX_I2C_READ:
> +	case DP_AUX_NATIVE_READ:
> +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> +		request = msg->request;
> +		is_read = true;
> +		break;
> +	default:
> +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> +			msg->request);
> +		return -EINVAL;
> +	}
> +
> +	if (msg->size == 0) {
> +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> +					     msg->address +
> accessed_bytes,
> +					     msg->buffer +
> accessed_bytes, 0);
> +	} else {
> +		while (accessed_bytes < msg->size) {
> +			size_t to_access =
> +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> +				      msg->size - accessed_bytes);
> +
> +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> +						     is_read, request,
> +							 msg->address +
> accessed_bytes,
> +							 msg->buffer +
> accessed_bytes,
> +							 to_access);
> +
> +			if (ret) {
> +				drm_info(mtk_dp->drm_dev,
> +					 "Failed to do AUX transfer:
> %d\n", ret);
> +				break;
> +			}
> +			accessed_bytes += to_access;
> +		}
> +	}
> +
> +	if (ret) {
> +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> DP_AUX_I2C_REPLY_NACK;
> +		return ret;
> +	}
> +
> +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> +	return msg->size;
> +}


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  7:30     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> +				   struct drm_dp_aux_msg *msg)
> +{
> +	struct mtk_dp *mtk_dp;
> +	bool is_read;
> +	u8 request;
> +	size_t accessed_bytes = 0;
> +	int ret = 0;
> +
> +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> +
> +	if (!mtk_dp->train_info.cable_plugged_in ||
> +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;

Changing state here has no any effect, so drop this.

> +		return -EAGAIN;
> +	}
> +
> +	switch (msg->request) {
> +	case DP_AUX_I2C_MOT:
> +	case DP_AUX_I2C_WRITE:
> +	case DP_AUX_NATIVE_WRITE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> +		request = msg->request &
> ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> +		is_read = false;
> +		break;
> +	case DP_AUX_I2C_READ:
> +	case DP_AUX_NATIVE_READ:
> +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> +		request = msg->request;
> +		is_read = true;
> +		break;
> +	default:
> +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> +			msg->request);
> +		return -EINVAL;
> +	}
> +
> +	if (msg->size == 0) {
> +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> +					     msg->address +
> accessed_bytes,
> +					     msg->buffer +
> accessed_bytes, 0);
> +	} else {
> +		while (accessed_bytes < msg->size) {
> +			size_t to_access =
> +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> +				      msg->size - accessed_bytes);
> +
> +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> +						     is_read, request,
> +							 msg->address +
> accessed_bytes,
> +							 msg->buffer +
> accessed_bytes,
> +							 to_access);
> +
> +			if (ret) {
> +				drm_info(mtk_dp->drm_dev,
> +					 "Failed to do AUX transfer:
> %d\n", ret);
> +				break;
> +			}
> +			accessed_bytes += to_access;
> +		}
> +	}
> +
> +	if (ret) {
> +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> DP_AUX_I2C_REPLY_NACK;
> +		return ret;
> +	}
> +
> +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> +	return msg->size;
> +}


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  7:30     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> +				   struct drm_dp_aux_msg *msg)
> +{
> +	struct mtk_dp *mtk_dp;
> +	bool is_read;
> +	u8 request;
> +	size_t accessed_bytes = 0;
> +	int ret = 0;
> +
> +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> +
> +	if (!mtk_dp->train_info.cable_plugged_in ||
> +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;

Changing state here has no any effect, so drop this.

> +		return -EAGAIN;
> +	}
> +
> +	switch (msg->request) {
> +	case DP_AUX_I2C_MOT:
> +	case DP_AUX_I2C_WRITE:
> +	case DP_AUX_NATIVE_WRITE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> +		request = msg->request &
> ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> +		is_read = false;
> +		break;
> +	case DP_AUX_I2C_READ:
> +	case DP_AUX_NATIVE_READ:
> +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> +		request = msg->request;
> +		is_read = true;
> +		break;
> +	default:
> +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> +			msg->request);
> +		return -EINVAL;
> +	}
> +
> +	if (msg->size == 0) {
> +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> +					     msg->address +
> accessed_bytes,
> +					     msg->buffer +
> accessed_bytes, 0);
> +	} else {
> +		while (accessed_bytes < msg->size) {
> +			size_t to_access =
> +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> +				      msg->size - accessed_bytes);
> +
> +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> +						     is_read, request,
> +							 msg->address +
> accessed_bytes,
> +							 msg->buffer +
> accessed_bytes,
> +							 to_access);
> +
> +			if (ret) {
> +				drm_info(mtk_dp->drm_dev,
> +					 "Failed to do AUX transfer:
> %d\n", ret);
> +				break;
> +			}
> +			accessed_bytes += to_access;
> +		}
> +	}
> +
> +	if (ret) {
> +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> DP_AUX_I2C_REPLY_NACK;
> +		return ret;
> +	}
> +
> +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> +	return msg->size;
> +}


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  7:30     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> +				   struct drm_dp_aux_msg *msg)
> +{
> +	struct mtk_dp *mtk_dp;
> +	bool is_read;
> +	u8 request;
> +	size_t accessed_bytes = 0;
> +	int ret = 0;
> +
> +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> +
> +	if (!mtk_dp->train_info.cable_plugged_in ||
> +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;

Changing state here has no any effect, so drop this.

> +		return -EAGAIN;
> +	}
> +
> +	switch (msg->request) {
> +	case DP_AUX_I2C_MOT:
> +	case DP_AUX_I2C_WRITE:
> +	case DP_AUX_NATIVE_WRITE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> +		request = msg->request &
> ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> +		is_read = false;
> +		break;
> +	case DP_AUX_I2C_READ:
> +	case DP_AUX_NATIVE_READ:
> +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> +		request = msg->request;
> +		is_read = true;
> +		break;
> +	default:
> +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> +			msg->request);
> +		return -EINVAL;
> +	}
> +
> +	if (msg->size == 0) {
> +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> +					     msg->address +
> accessed_bytes,
> +					     msg->buffer +
> accessed_bytes, 0);
> +	} else {
> +		while (accessed_bytes < msg->size) {
> +			size_t to_access =
> +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> +				      msg->size - accessed_bytes);
> +
> +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> +						     is_read, request,
> +							 msg->address +
> accessed_bytes,
> +							 msg->buffer +
> accessed_bytes,
> +							 to_access);
> +
> +			if (ret) {
> +				drm_info(mtk_dp->drm_dev,
> +					 "Failed to do AUX transfer:
> %d\n", ret);
> +				break;
> +			}
> +			accessed_bytes += to_access;
> +		}
> +	}
> +
> +	if (ret) {
> +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> DP_AUX_I2C_REPLY_NACK;
> +		return ret;
> +	}
> +
> +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> +	return msg->size;
> +}


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  7:47     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:47 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> +{
> +	ssize_t ret;
> +	u8 sink_count;
> +	bool locked;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> +	u32 link_status_reg = DP_LANE0_1_STATUS;
> +
> +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> &sink_count);
> +	if (ret < 0) {
> +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> %ld\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> link_status,
> +			       sizeof(link_status));
> +	if (!ret) {
> +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> %ld\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	locked = drm_dp_channel_eq_ok(link_status,
> +				      mtk_dp->train_info.lane_count);
> +	if (!locked && mtk_dp->train_state >
> MTK_DP_TRAIN_STATE_TRAINING_PRE)

Before enter this function, mtk_dp->train_state is set to
MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.

> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> +
> +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> DP_DEVICE_SERVICE_IRQ_VECTOR,
> +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> +
> +	if (DP_GET_SINK_COUNT(sink_count) &&
> +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> +		mtk_dp->train_info.check_cap_count = 0;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;

Why change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
mtk_dp_parse_capabilities() is true then change to
MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
different.

Regards,
CK

> +		msleep(20);
> +	}
> +
> +	return 0;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  7:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:47 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> +{
> +	ssize_t ret;
> +	u8 sink_count;
> +	bool locked;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> +	u32 link_status_reg = DP_LANE0_1_STATUS;
> +
> +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> &sink_count);
> +	if (ret < 0) {
> +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> %ld\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> link_status,
> +			       sizeof(link_status));
> +	if (!ret) {
> +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> %ld\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	locked = drm_dp_channel_eq_ok(link_status,
> +				      mtk_dp->train_info.lane_count);
> +	if (!locked && mtk_dp->train_state >
> MTK_DP_TRAIN_STATE_TRAINING_PRE)

Before enter this function, mtk_dp->train_state is set to
MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.

> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> +
> +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> DP_DEVICE_SERVICE_IRQ_VECTOR,
> +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> +
> +	if (DP_GET_SINK_COUNT(sink_count) &&
> +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> +		mtk_dp->train_info.check_cap_count = 0;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;

Why change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
mtk_dp_parse_capabilities() is true then change to
MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
different.

Regards,
CK

> +		msleep(20);
> +	}
> +
> +	return 0;
> +}
> +


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  7:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:47 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> +{
> +	ssize_t ret;
> +	u8 sink_count;
> +	bool locked;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> +	u32 link_status_reg = DP_LANE0_1_STATUS;
> +
> +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> &sink_count);
> +	if (ret < 0) {
> +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> %ld\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> link_status,
> +			       sizeof(link_status));
> +	if (!ret) {
> +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> %ld\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	locked = drm_dp_channel_eq_ok(link_status,
> +				      mtk_dp->train_info.lane_count);
> +	if (!locked && mtk_dp->train_state >
> MTK_DP_TRAIN_STATE_TRAINING_PRE)

Before enter this function, mtk_dp->train_state is set to
MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.

> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> +
> +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> DP_DEVICE_SERVICE_IRQ_VECTOR,
> +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> +
> +	if (DP_GET_SINK_COUNT(sink_count) &&
> +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> +		mtk_dp->train_info.check_cap_count = 0;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;

Why change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
mtk_dp_parse_capabilities() is true then change to
MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
different.

Regards,
CK

> +		msleep(20);
> +	}
> +
> +	return 0;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  7:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:47 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> +{
> +	ssize_t ret;
> +	u8 sink_count;
> +	bool locked;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> +	u32 link_status_reg = DP_LANE0_1_STATUS;
> +
> +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> &sink_count);
> +	if (ret < 0) {
> +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> %ld\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> link_status,
> +			       sizeof(link_status));
> +	if (!ret) {
> +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> %ld\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	locked = drm_dp_channel_eq_ok(link_status,
> +				      mtk_dp->train_info.lane_count);
> +	if (!locked && mtk_dp->train_state >
> MTK_DP_TRAIN_STATE_TRAINING_PRE)

Before enter this function, mtk_dp->train_state is set to
MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.

> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> +
> +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> DP_DEVICE_SERVICE_IRQ_VECTOR,
> +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> +
> +	if (DP_GET_SINK_COUNT(sink_count) &&
> +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> +		mtk_dp->train_info.check_cap_count = 0;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;

Why change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
mtk_dp_parse_capabilities() is true then change to
MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
different.

Regards,
CK

> +		msleep(20);
> +	}
> +
> +	return 0;
> +}
> +


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  7:47     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  7:47 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> +{
> +	ssize_t ret;
> +	u8 sink_count;
> +	bool locked;
> +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> +	u32 link_status_reg = DP_LANE0_1_STATUS;
> +
> +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> &sink_count);
> +	if (ret < 0) {
> +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> %ld\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> link_status,
> +			       sizeof(link_status));
> +	if (!ret) {
> +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> %ld\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	locked = drm_dp_channel_eq_ok(link_status,
> +				      mtk_dp->train_info.lane_count);
> +	if (!locked && mtk_dp->train_state >
> MTK_DP_TRAIN_STATE_TRAINING_PRE)

Before enter this function, mtk_dp->train_state is set to
MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.

> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> +
> +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> DP_DEVICE_SERVICE_IRQ_VECTOR,
> +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> +
> +	if (DP_GET_SINK_COUNT(sink_count) &&
> +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> +		mtk_dp->train_info.check_cap_count = 0;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;

Why change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
mtk_dp_parse_capabilities() is true then change to
MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
different.

Regards,
CK

> +		msleep(20);
> +	}
> +
> +	return 0;
> +}
> +


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  8:01     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:01 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> +{
> +	switch (mtk_dp->state) {

Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
calling mtk_dp_state_handler() out of mtk_dp_train_handler().

Regards,
CK

> +	case MTK_DP_STATE_INITIAL:
> +		mtk_dp_video_mute(mtk_dp, true);
> +		mtk_dp->state = MTK_DP_STATE_IDLE;
> +		break;
> +
> +	case MTK_DP_STATE_IDLE:
> +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> +		break;
> +
> +	case MTK_DP_STATE_PREPARE:
> +		mtk_dp_video_config(mtk_dp);
> +		mtk_dp_video_enable(mtk_dp, true);
> +
> +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> +		break;
> +
> +	case MTK_DP_STATE_NORMAL:
> +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +			mtk_dp->state = MTK_DP_STATE_IDLE;
> +		}
> +		break;
> +
> +	default:
> +		break;
> +	}
> +}


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  8:01     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:01 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> +{
> +	switch (mtk_dp->state) {

Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
calling mtk_dp_state_handler() out of mtk_dp_train_handler().

Regards,
CK

> +	case MTK_DP_STATE_INITIAL:
> +		mtk_dp_video_mute(mtk_dp, true);
> +		mtk_dp->state = MTK_DP_STATE_IDLE;
> +		break;
> +
> +	case MTK_DP_STATE_IDLE:
> +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> +		break;
> +
> +	case MTK_DP_STATE_PREPARE:
> +		mtk_dp_video_config(mtk_dp);
> +		mtk_dp_video_enable(mtk_dp, true);
> +
> +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> +		break;
> +
> +	case MTK_DP_STATE_NORMAL:
> +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +			mtk_dp->state = MTK_DP_STATE_IDLE;
> +		}
> +		break;
> +
> +	default:
> +		break;
> +	}
> +}


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  8:01     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:01 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> +{
> +	switch (mtk_dp->state) {

Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
calling mtk_dp_state_handler() out of mtk_dp_train_handler().

Regards,
CK

> +	case MTK_DP_STATE_INITIAL:
> +		mtk_dp_video_mute(mtk_dp, true);
> +		mtk_dp->state = MTK_DP_STATE_IDLE;
> +		break;
> +
> +	case MTK_DP_STATE_IDLE:
> +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> +		break;
> +
> +	case MTK_DP_STATE_PREPARE:
> +		mtk_dp_video_config(mtk_dp);
> +		mtk_dp_video_enable(mtk_dp, true);
> +
> +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> +		break;
> +
> +	case MTK_DP_STATE_NORMAL:
> +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +			mtk_dp->state = MTK_DP_STATE_IDLE;
> +		}
> +		break;
> +
> +	default:
> +		break;
> +	}
> +}


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  8:01     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:01 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> +{
> +	switch (mtk_dp->state) {

Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
calling mtk_dp_state_handler() out of mtk_dp_train_handler().

Regards,
CK

> +	case MTK_DP_STATE_INITIAL:
> +		mtk_dp_video_mute(mtk_dp, true);
> +		mtk_dp->state = MTK_DP_STATE_IDLE;
> +		break;
> +
> +	case MTK_DP_STATE_IDLE:
> +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> +		break;
> +
> +	case MTK_DP_STATE_PREPARE:
> +		mtk_dp_video_config(mtk_dp);
> +		mtk_dp_video_enable(mtk_dp, true);
> +
> +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> +		break;
> +
> +	case MTK_DP_STATE_NORMAL:
> +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +			mtk_dp->state = MTK_DP_STATE_IDLE;
> +		}
> +		break;
> +
> +	default:
> +		break;
> +	}
> +}


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  8:01     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:01 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> +{
> +	switch (mtk_dp->state) {

Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
calling mtk_dp_state_handler() out of mtk_dp_train_handler().

Regards,
CK

> +	case MTK_DP_STATE_INITIAL:
> +		mtk_dp_video_mute(mtk_dp, true);
> +		mtk_dp->state = MTK_DP_STATE_IDLE;
> +		break;
> +
> +	case MTK_DP_STATE_IDLE:
> +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> +		break;
> +
> +	case MTK_DP_STATE_PREPARE:
> +		mtk_dp_video_config(mtk_dp);
> +		mtk_dp_video_enable(mtk_dp, true);
> +
> +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> +		break;
> +
> +	case MTK_DP_STATE_NORMAL:
> +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +			mtk_dp->state = MTK_DP_STATE_IDLE;
> +		}
> +		break;
> +
> +	default:
> +		break;
> +	}
> +}


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  8:12     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:12 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> +{
> +	int ret = 0;
> +	u8 lane_count;
> +	u8 link_rate;
> +	u8 train_limit;
> +	u8 max_link_rate;
> +	u8 plug_wait;
> +
> +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> 0;
> +	     --plug_wait)
> +		/* Avoid short pulses on the HPD isr */
> +		usleep_range(1000, 5000);
> +	if (plug_wait == 0) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

> +		return -ENODEV;
> +	}
> +
> +	link_rate = mtk_dp->rx_cap[1];
> +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> +
> +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> link_rate);
> +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> lane_count);
> +	link_rate = mtk_dp->train_info.link_rate;
> +	lane_count = mtk_dp->train_info.lane_count;
> +
> +	switch (link_rate) {
> +	case MTK_DP_LINKRATE_RBR:
> +	case MTK_DP_LINKRATE_HBR:
> +	case MTK_DP_LINKRATE_HBR2:
> +	case MTK_DP_LINKRATE_HBR25:
> +	case MTK_DP_LINKRATE_HBR3:
> +		break;
> +	default:
> +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> +		break;
> +	};
> +
> +	max_link_rate = link_rate;
> +	for (train_limit = 6; train_limit > 0; train_limit--) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +
> +		mtk_dp_train_change_mode(mtk_dp);
> +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> +		if (ret)
> +			return ret;
> +
> +		if (!mtk_dp->train_info.cr_done) {
> +			switch (link_rate) {
> +			case MTK_DP_LINKRATE_RBR:
> +				lane_count = lane_count / 2;
> +				link_rate = max_link_rate;
> +				if (lane_count == 0) {
> +					mtk_dp->train_state =
> +						MTK_DP_TRAIN_STATE_DPID
> LE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

Regards,
CK

> +					return -EIO;
> +				}
> +				break;
> +			case MTK_DP_LINKRATE_HBR:
> +				link_rate = MTK_DP_LINKRATE_RBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR2:
> +				link_rate = MTK_DP_LINKRATE_HBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR3:
> +				link_rate = MTK_DP_LINKRATE_HBR2;
> +				break;
> +			default:
> +				return -EINVAL;
> +			};
> +		} else if (!mtk_dp->train_info.eq_done) {
> +			if (lane_count == 0)
> +				return -EIO;
> +
> +			lane_count /= 2;
> +		} else {
> +			break;
> +		}
> +	}
> +
> +	if (train_limit == 0)
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  8:12     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:12 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> +{
> +	int ret = 0;
> +	u8 lane_count;
> +	u8 link_rate;
> +	u8 train_limit;
> +	u8 max_link_rate;
> +	u8 plug_wait;
> +
> +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> 0;
> +	     --plug_wait)
> +		/* Avoid short pulses on the HPD isr */
> +		usleep_range(1000, 5000);
> +	if (plug_wait == 0) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

> +		return -ENODEV;
> +	}
> +
> +	link_rate = mtk_dp->rx_cap[1];
> +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> +
> +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> link_rate);
> +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> lane_count);
> +	link_rate = mtk_dp->train_info.link_rate;
> +	lane_count = mtk_dp->train_info.lane_count;
> +
> +	switch (link_rate) {
> +	case MTK_DP_LINKRATE_RBR:
> +	case MTK_DP_LINKRATE_HBR:
> +	case MTK_DP_LINKRATE_HBR2:
> +	case MTK_DP_LINKRATE_HBR25:
> +	case MTK_DP_LINKRATE_HBR3:
> +		break;
> +	default:
> +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> +		break;
> +	};
> +
> +	max_link_rate = link_rate;
> +	for (train_limit = 6; train_limit > 0; train_limit--) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +
> +		mtk_dp_train_change_mode(mtk_dp);
> +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> +		if (ret)
> +			return ret;
> +
> +		if (!mtk_dp->train_info.cr_done) {
> +			switch (link_rate) {
> +			case MTK_DP_LINKRATE_RBR:
> +				lane_count = lane_count / 2;
> +				link_rate = max_link_rate;
> +				if (lane_count == 0) {
> +					mtk_dp->train_state =
> +						MTK_DP_TRAIN_STATE_DPID
> LE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

Regards,
CK

> +					return -EIO;
> +				}
> +				break;
> +			case MTK_DP_LINKRATE_HBR:
> +				link_rate = MTK_DP_LINKRATE_RBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR2:
> +				link_rate = MTK_DP_LINKRATE_HBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR3:
> +				link_rate = MTK_DP_LINKRATE_HBR2;
> +				break;
> +			default:
> +				return -EINVAL;
> +			};
> +		} else if (!mtk_dp->train_info.eq_done) {
> +			if (lane_count == 0)
> +				return -EIO;
> +
> +			lane_count /= 2;
> +		} else {
> +			break;
> +		}
> +	}
> +
> +	if (train_limit == 0)
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  8:12     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:12 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> +{
> +	int ret = 0;
> +	u8 lane_count;
> +	u8 link_rate;
> +	u8 train_limit;
> +	u8 max_link_rate;
> +	u8 plug_wait;
> +
> +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> 0;
> +	     --plug_wait)
> +		/* Avoid short pulses on the HPD isr */
> +		usleep_range(1000, 5000);
> +	if (plug_wait == 0) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

> +		return -ENODEV;
> +	}
> +
> +	link_rate = mtk_dp->rx_cap[1];
> +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> +
> +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> link_rate);
> +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> lane_count);
> +	link_rate = mtk_dp->train_info.link_rate;
> +	lane_count = mtk_dp->train_info.lane_count;
> +
> +	switch (link_rate) {
> +	case MTK_DP_LINKRATE_RBR:
> +	case MTK_DP_LINKRATE_HBR:
> +	case MTK_DP_LINKRATE_HBR2:
> +	case MTK_DP_LINKRATE_HBR25:
> +	case MTK_DP_LINKRATE_HBR3:
> +		break;
> +	default:
> +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> +		break;
> +	};
> +
> +	max_link_rate = link_rate;
> +	for (train_limit = 6; train_limit > 0; train_limit--) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +
> +		mtk_dp_train_change_mode(mtk_dp);
> +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> +		if (ret)
> +			return ret;
> +
> +		if (!mtk_dp->train_info.cr_done) {
> +			switch (link_rate) {
> +			case MTK_DP_LINKRATE_RBR:
> +				lane_count = lane_count / 2;
> +				link_rate = max_link_rate;
> +				if (lane_count == 0) {
> +					mtk_dp->train_state =
> +						MTK_DP_TRAIN_STATE_DPID
> LE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

Regards,
CK

> +					return -EIO;
> +				}
> +				break;
> +			case MTK_DP_LINKRATE_HBR:
> +				link_rate = MTK_DP_LINKRATE_RBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR2:
> +				link_rate = MTK_DP_LINKRATE_HBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR3:
> +				link_rate = MTK_DP_LINKRATE_HBR2;
> +				break;
> +			default:
> +				return -EINVAL;
> +			};
> +		} else if (!mtk_dp->train_info.eq_done) {
> +			if (lane_count == 0)
> +				return -EIO;
> +
> +			lane_count /= 2;
> +		} else {
> +			break;
> +		}
> +	}
> +
> +	if (train_limit == 0)
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  8:12     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:12 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> +{
> +	int ret = 0;
> +	u8 lane_count;
> +	u8 link_rate;
> +	u8 train_limit;
> +	u8 max_link_rate;
> +	u8 plug_wait;
> +
> +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> 0;
> +	     --plug_wait)
> +		/* Avoid short pulses on the HPD isr */
> +		usleep_range(1000, 5000);
> +	if (plug_wait == 0) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

> +		return -ENODEV;
> +	}
> +
> +	link_rate = mtk_dp->rx_cap[1];
> +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> +
> +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> link_rate);
> +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> lane_count);
> +	link_rate = mtk_dp->train_info.link_rate;
> +	lane_count = mtk_dp->train_info.lane_count;
> +
> +	switch (link_rate) {
> +	case MTK_DP_LINKRATE_RBR:
> +	case MTK_DP_LINKRATE_HBR:
> +	case MTK_DP_LINKRATE_HBR2:
> +	case MTK_DP_LINKRATE_HBR25:
> +	case MTK_DP_LINKRATE_HBR3:
> +		break;
> +	default:
> +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> +		break;
> +	};
> +
> +	max_link_rate = link_rate;
> +	for (train_limit = 6; train_limit > 0; train_limit--) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +
> +		mtk_dp_train_change_mode(mtk_dp);
> +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> +		if (ret)
> +			return ret;
> +
> +		if (!mtk_dp->train_info.cr_done) {
> +			switch (link_rate) {
> +			case MTK_DP_LINKRATE_RBR:
> +				lane_count = lane_count / 2;
> +				link_rate = max_link_rate;
> +				if (lane_count == 0) {
> +					mtk_dp->train_state =
> +						MTK_DP_TRAIN_STATE_DPID
> LE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

Regards,
CK

> +					return -EIO;
> +				}
> +				break;
> +			case MTK_DP_LINKRATE_HBR:
> +				link_rate = MTK_DP_LINKRATE_RBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR2:
> +				link_rate = MTK_DP_LINKRATE_HBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR3:
> +				link_rate = MTK_DP_LINKRATE_HBR2;
> +				break;
> +			default:
> +				return -EINVAL;
> +			};
> +		} else if (!mtk_dp->train_info.eq_done) {
> +			if (lane_count == 0)
> +				return -EIO;
> +
> +			lane_count /= 2;
> +		} else {
> +			break;
> +		}
> +	}
> +
> +	if (train_limit == 0)
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  8:12     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  8:12 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> +{
> +	int ret = 0;
> +	u8 lane_count;
> +	u8 link_rate;
> +	u8 train_limit;
> +	u8 max_link_rate;
> +	u8 plug_wait;
> +
> +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> 0;
> +	     --plug_wait)
> +		/* Avoid short pulses on the HPD isr */
> +		usleep_range(1000, 5000);
> +	if (plug_wait == 0) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

> +		return -ENODEV;
> +	}
> +
> +	link_rate = mtk_dp->rx_cap[1];
> +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> +
> +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> link_rate);
> +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> lane_count);
> +	link_rate = mtk_dp->train_info.link_rate;
> +	lane_count = mtk_dp->train_info.lane_count;
> +
> +	switch (link_rate) {
> +	case MTK_DP_LINKRATE_RBR:
> +	case MTK_DP_LINKRATE_HBR:
> +	case MTK_DP_LINKRATE_HBR2:
> +	case MTK_DP_LINKRATE_HBR25:
> +	case MTK_DP_LINKRATE_HBR3:
> +		break;
> +	default:
> +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> +		break;
> +	};
> +
> +	max_link_rate = link_rate;
> +	for (train_limit = 6; train_limit > 0; train_limit--) {
> +		mtk_dp->train_info.cr_done = false;
> +		mtk_dp->train_info.eq_done = false;
> +
> +		mtk_dp_train_change_mode(mtk_dp);
> +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> +		if (ret)
> +			return ret;
> +
> +		if (!mtk_dp->train_info.cr_done) {
> +			switch (link_rate) {
> +			case MTK_DP_LINKRATE_RBR:
> +				lane_count = lane_count / 2;
> +				link_rate = max_link_rate;
> +				if (lane_count == 0) {
> +					mtk_dp->train_state =
> +						MTK_DP_TRAIN_STATE_DPID
> LE;

After return, mtk_dp->train_state would be set to
MTK_DP_TRAIN_STATE_DPIDLE, so drop this.

Regards,
CK

> +					return -EIO;
> +				}
> +				break;
> +			case MTK_DP_LINKRATE_HBR:
> +				link_rate = MTK_DP_LINKRATE_RBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR2:
> +				link_rate = MTK_DP_LINKRATE_HBR;
> +				break;
> +			case MTK_DP_LINKRATE_HBR3:
> +				link_rate = MTK_DP_LINKRATE_HBR2;
> +				break;
> +			default:
> +				return -EINVAL;
> +			};
> +		} else if (!mtk_dp->train_info.eq_done) {
> +			if (lane_count == 0)
> +				return -EIO;
> +
> +			lane_count /= 2;
> +		} else {
> +			break;
> +		}
> +	}
> +
> +	if (train_limit == 0)
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-07  9:04     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  9:04 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);

For eDP, when does 'unplug' happen? Explain this or move unplug
processing to DP patch.

Regards,
CK

> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  9:04     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  9:04 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);

For eDP, when does 'unplug' happen? Explain this or move unplug
processing to DP patch.

Regards,
CK

> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  9:04     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  9:04 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);

For eDP, when does 'unplug' happen? Explain this or move unplug
processing to DP patch.

Regards,
CK

> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  9:04     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  9:04 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);

For eDP, when does 'unplug' happen? Explain this or move unplug
processing to DP patch.

Regards,
CK

> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07  9:04     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-07  9:04 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)
> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);

For eDP, when does 'unplug' happen? Explain this or move unplug
processing to DP patch.

Regards,
CK

> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, mtk_dp->max_linkrate,
> +				      buf[mtk_dp->max_linkrate]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, mtk_dp->max_lanes,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07  6:21     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07 12:24       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> 
> event is always > 0, isn't it?
> 
Hello CK,

ok, I will move this to dp patch.

> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> 
> I think this ISR would come once. If bridge has not attached, the drm
> core would lost this event. Maybe you should enable eDP hardware
> after
> bridge attached or send this event when attached.
> 

for edp patch, I will move it to (mtk_dp_bridge_attach).
for dp patch, I will add it back.

> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> 
> Executing this thread imply cable_state_change = true, so drop
> cable_state_change.
> 

In mtk_dp_hpd_isr_handler(), there is another irq
"MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt to
source device. it's not about connected status, so I think we still
need this.

> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> 
> I do not like two variable to present one thing. If
> 
> mtk_dp->train_info.cable_plugged_in = false
> and
> mtk_dp_plug_state(mtk_dp) = ture
> 
> What does this mean? I think this mean 'now' is connected because
> cable_plugged_in is old information and mtk_dp_plug_state() is
> current
> information.
> 
> But I would like to keep cable_plugged_in and drop
> mtk_dp_plug_state()
> because cable_plugged_in would be changed in isr and it would be the
> same as mtk_dp_plug_state().
> 
> Regards,
> CK
> 

ok, I will drop this.

BRs,
Rex

> > +			mtk_dp_video_mute(mtk_dp, true);
> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:24       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> 
> event is always > 0, isn't it?
> 
Hello CK,

ok, I will move this to dp patch.

> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> 
> I think this ISR would come once. If bridge has not attached, the drm
> core would lost this event. Maybe you should enable eDP hardware
> after
> bridge attached or send this event when attached.
> 

for edp patch, I will move it to (mtk_dp_bridge_attach).
for dp patch, I will add it back.

> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> 
> Executing this thread imply cable_state_change = true, so drop
> cable_state_change.
> 

In mtk_dp_hpd_isr_handler(), there is another irq
"MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt to
source device. it's not about connected status, so I think we still
need this.

> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> 
> I do not like two variable to present one thing. If
> 
> mtk_dp->train_info.cable_plugged_in = false
> and
> mtk_dp_plug_state(mtk_dp) = ture
> 
> What does this mean? I think this mean 'now' is connected because
> cable_plugged_in is old information and mtk_dp_plug_state() is
> current
> information.
> 
> But I would like to keep cable_plugged_in and drop
> mtk_dp_plug_state()
> because cable_plugged_in would be changed in isr and it would be the
> same as mtk_dp_plug_state().
> 
> Regards,
> CK
> 

ok, I will drop this.

BRs,
Rex

> > +			mtk_dp_video_mute(mtk_dp, true);
> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:24       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> 
> event is always > 0, isn't it?
> 
Hello CK,

ok, I will move this to dp patch.

> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> 
> I think this ISR would come once. If bridge has not attached, the drm
> core would lost this event. Maybe you should enable eDP hardware
> after
> bridge attached or send this event when attached.
> 

for edp patch, I will move it to (mtk_dp_bridge_attach).
for dp patch, I will add it back.

> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> 
> Executing this thread imply cable_state_change = true, so drop
> cable_state_change.
> 

In mtk_dp_hpd_isr_handler(), there is another irq
"MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt to
source device. it's not about connected status, so I think we still
need this.

> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> 
> I do not like two variable to present one thing. If
> 
> mtk_dp->train_info.cable_plugged_in = false
> and
> mtk_dp_plug_state(mtk_dp) = ture
> 
> What does this mean? I think this mean 'now' is connected because
> cable_plugged_in is old information and mtk_dp_plug_state() is
> current
> information.
> 
> But I would like to keep cable_plugged_in and drop
> mtk_dp_plug_state()
> because cable_plugged_in would be changed in isr and it would be the
> same as mtk_dp_plug_state().
> 
> Regards,
> CK
> 

ok, I will drop this.

BRs,
Rex

> > +			mtk_dp_video_mute(mtk_dp, true);
> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:24       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> 
> event is always > 0, isn't it?
> 
Hello CK,

ok, I will move this to dp patch.

> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> 
> I think this ISR would come once. If bridge has not attached, the drm
> core would lost this event. Maybe you should enable eDP hardware
> after
> bridge attached or send this event when attached.
> 

for edp patch, I will move it to (mtk_dp_bridge_attach).
for dp patch, I will add it back.

> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> 
> Executing this thread imply cable_state_change = true, so drop
> cable_state_change.
> 

In mtk_dp_hpd_isr_handler(), there is another irq
"MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt to
source device. it's not about connected status, so I think we still
need this.

> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> 
> I do not like two variable to present one thing. If
> 
> mtk_dp->train_info.cable_plugged_in = false
> and
> mtk_dp_plug_state(mtk_dp) = ture
> 
> What does this mean? I think this mean 'now' is connected because
> cable_plugged_in is old information and mtk_dp_plug_state() is
> current
> information.
> 
> But I would like to keep cable_plugged_in and drop
> mtk_dp_plug_state()
> because cable_plugged_in would be changed in isr and it would be the
> same as mtk_dp_plug_state().
> 
> Regards,
> CK
> 

ok, I will drop this.

BRs,
Rex

> > +			mtk_dp_video_mute(mtk_dp, true);
> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:24       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> 
> event is always > 0, isn't it?
> 
Hello CK,

ok, I will move this to dp patch.

> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> 
> I think this ISR would come once. If bridge has not attached, the drm
> core would lost this event. Maybe you should enable eDP hardware
> after
> bridge attached or send this event when attached.
> 

for edp patch, I will move it to (mtk_dp_bridge_attach).
for dp patch, I will add it back.

> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> 
> Executing this thread imply cable_state_change = true, so drop
> cable_state_change.
> 

In mtk_dp_hpd_isr_handler(), there is another irq
"MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt to
source device. it's not about connected status, so I think we still
need this.

> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> 
> I do not like two variable to present one thing. If
> 
> mtk_dp->train_info.cable_plugged_in = false
> and
> mtk_dp_plug_state(mtk_dp) = ture
> 
> What does this mean? I think this mean 'now' is connected because
> cable_plugged_in is old information and mtk_dp_plug_state() is
> current
> information.
> 
> But I would like to keep cable_plugged_in and drop
> mtk_dp_plug_state()
> because cable_plugged_in would be changed in isr and it would be the
> same as mtk_dp_plug_state().
> 
> Regards,
> CK
> 

ok, I will drop this.

BRs,
Rex

> > +			mtk_dp_video_mute(mtk_dp, true);
> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07  6:44     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07 12:44       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:44 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	bool training_done = false;
> > +	short max_retry = 50;
> > +	int ret = 0;
> > +
> > +	do {
> > +		switch (mtk_dp->train_state) {
> > +		case MTK_DP_TRAIN_STATE_STARTUP:
> 
> mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
> though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> If
> HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
> for init state.
> 

Hello CK,

I think we don't need MTK_DP_TRAIN_STATE_NONE.
Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKCAP;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > +				mtk_dp->train_info.check_cap_count = 0;
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKEDID;
> > +			} else {
> > +				mtk_dp->train_info.check_cap_count++;
> > +
> > +				if (mtk_dp->train_info.check_cap_count
> > > 
> > 
> > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > ) {
> > +					mtk_dp-
> > > train_info.check_cap_count = 0;
> > 
> > +					mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +					ret = -ETIMEDOUT;
> > +				}
> > +			}
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> 
> MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> 
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > +			ret = mtk_dp_train_start(mtk_dp);
> > +			if (ret == 0) {
> > +				mtk_dp_video_mute(mtk_dp, true);
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_NORMAL;
> > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > has_fec);
> > 
> > +			} else if (ret != -EAGAIN) {
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +			}
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			training_done = true;
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> 
> When would this case happen?
> 
> Regards,
> CK

Yes, if it's disconnected if we are still training for dp.
or failed to training min spec RBR.

BRs,
Rex
> 
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +
> > +		if (ret) {
> > +			if (ret == -EAGAIN)
> > +				continue;
> > +			/*
> > +			 * If we get any other error number, it doesn't
> > +			 * make any sense to keep iterating.
> > +			 */
> > +			break;
> > +		}
> > +	} while (!training_done || --max_retry);
> > +
> > +	return ret;
> > +}
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:44       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:44 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	bool training_done = false;
> > +	short max_retry = 50;
> > +	int ret = 0;
> > +
> > +	do {
> > +		switch (mtk_dp->train_state) {
> > +		case MTK_DP_TRAIN_STATE_STARTUP:
> 
> mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
> though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> If
> HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
> for init state.
> 

Hello CK,

I think we don't need MTK_DP_TRAIN_STATE_NONE.
Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKCAP;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > +				mtk_dp->train_info.check_cap_count = 0;
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKEDID;
> > +			} else {
> > +				mtk_dp->train_info.check_cap_count++;
> > +
> > +				if (mtk_dp->train_info.check_cap_count
> > > 
> > 
> > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > ) {
> > +					mtk_dp-
> > > train_info.check_cap_count = 0;
> > 
> > +					mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +					ret = -ETIMEDOUT;
> > +				}
> > +			}
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> 
> MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> 
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > +			ret = mtk_dp_train_start(mtk_dp);
> > +			if (ret == 0) {
> > +				mtk_dp_video_mute(mtk_dp, true);
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_NORMAL;
> > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > has_fec);
> > 
> > +			} else if (ret != -EAGAIN) {
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +			}
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			training_done = true;
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> 
> When would this case happen?
> 
> Regards,
> CK

Yes, if it's disconnected if we are still training for dp.
or failed to training min spec RBR.

BRs,
Rex
> 
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +
> > +		if (ret) {
> > +			if (ret == -EAGAIN)
> > +				continue;
> > +			/*
> > +			 * If we get any other error number, it doesn't
> > +			 * make any sense to keep iterating.
> > +			 */
> > +			break;
> > +		}
> > +	} while (!training_done || --max_retry);
> > +
> > +	return ret;
> > +}
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:44       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:44 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	bool training_done = false;
> > +	short max_retry = 50;
> > +	int ret = 0;
> > +
> > +	do {
> > +		switch (mtk_dp->train_state) {
> > +		case MTK_DP_TRAIN_STATE_STARTUP:
> 
> mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
> though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> If
> HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
> for init state.
> 

Hello CK,

I think we don't need MTK_DP_TRAIN_STATE_NONE.
Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKCAP;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > +				mtk_dp->train_info.check_cap_count = 0;
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKEDID;
> > +			} else {
> > +				mtk_dp->train_info.check_cap_count++;
> > +
> > +				if (mtk_dp->train_info.check_cap_count
> > > 
> > 
> > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > ) {
> > +					mtk_dp-
> > > train_info.check_cap_count = 0;
> > 
> > +					mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +					ret = -ETIMEDOUT;
> > +				}
> > +			}
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> 
> MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> 
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > +			ret = mtk_dp_train_start(mtk_dp);
> > +			if (ret == 0) {
> > +				mtk_dp_video_mute(mtk_dp, true);
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_NORMAL;
> > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > has_fec);
> > 
> > +			} else if (ret != -EAGAIN) {
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +			}
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			training_done = true;
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> 
> When would this case happen?
> 
> Regards,
> CK

Yes, if it's disconnected if we are still training for dp.
or failed to training min spec RBR.

BRs,
Rex
> 
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +
> > +		if (ret) {
> > +			if (ret == -EAGAIN)
> > +				continue;
> > +			/*
> > +			 * If we get any other error number, it doesn't
> > +			 * make any sense to keep iterating.
> > +			 */
> > +			break;
> > +		}
> > +	} while (!training_done || --max_retry);
> > +
> > +	return ret;
> > +}
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:44       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:44 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	bool training_done = false;
> > +	short max_retry = 50;
> > +	int ret = 0;
> > +
> > +	do {
> > +		switch (mtk_dp->train_state) {
> > +		case MTK_DP_TRAIN_STATE_STARTUP:
> 
> mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
> though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> If
> HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
> for init state.
> 

Hello CK,

I think we don't need MTK_DP_TRAIN_STATE_NONE.
Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKCAP;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > +				mtk_dp->train_info.check_cap_count = 0;
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKEDID;
> > +			} else {
> > +				mtk_dp->train_info.check_cap_count++;
> > +
> > +				if (mtk_dp->train_info.check_cap_count
> > > 
> > 
> > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > ) {
> > +					mtk_dp-
> > > train_info.check_cap_count = 0;
> > 
> > +					mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +					ret = -ETIMEDOUT;
> > +				}
> > +			}
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> 
> MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> 
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > +			ret = mtk_dp_train_start(mtk_dp);
> > +			if (ret == 0) {
> > +				mtk_dp_video_mute(mtk_dp, true);
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_NORMAL;
> > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > has_fec);
> > 
> > +			} else if (ret != -EAGAIN) {
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +			}
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			training_done = true;
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> 
> When would this case happen?
> 
> Regards,
> CK

Yes, if it's disconnected if we are still training for dp.
or failed to training min spec RBR.

BRs,
Rex
> 
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +
> > +		if (ret) {
> > +			if (ret == -EAGAIN)
> > +				continue;
> > +			/*
> > +			 * If we get any other error number, it doesn't
> > +			 * make any sense to keep iterating.
> > +			 */
> > +			break;
> > +		}
> > +	} while (!training_done || --max_retry);
> > +
> > +	return ret;
> > +}
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:44       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:44 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	bool training_done = false;
> > +	short max_retry = 50;
> > +	int ret = 0;
> > +
> > +	do {
> > +		switch (mtk_dp->train_state) {
> > +		case MTK_DP_TRAIN_STATE_STARTUP:
> 
> mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP even
> though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> If
> HPD ISR is not redundant, create a new state MTK_DP_TRAIN_STATE_NONE
> for init state.
> 

Hello CK,

I think we don't need MTK_DP_TRAIN_STATE_NONE.
Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKCAP;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > +				mtk_dp->train_info.check_cap_count = 0;
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_CHECKEDID;
> > +			} else {
> > +				mtk_dp->train_info.check_cap_count++;
> > +
> > +				if (mtk_dp->train_info.check_cap_count
> > > 
> > 
> > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > ) {
> > +					mtk_dp-
> > > train_info.check_cap_count = 0;
> > 
> > +					mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +					ret = -ETIMEDOUT;
> > +				}
> > +			}
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> 
> MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> 
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_TRAINING;
> > +			break;
> > +
> > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > +			ret = mtk_dp_train_start(mtk_dp);
> > +			if (ret == 0) {
> > +				mtk_dp_video_mute(mtk_dp, true);
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_NORMAL;
> > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > has_fec);
> > 
> > +			} else if (ret != -EAGAIN) {
> > +				mtk_dp->train_state =
> > MTK_DP_TRAIN_STATE_DPIDLE;
> > +			}
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > +			mtk_dp_state_handler(mtk_dp);
> > +			training_done = true;
> > +			break;
> > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> 
> When would this case happen?
> 
> Regards,
> CK

Yes, if it's disconnected if we are still training for dp.
or failed to training min spec RBR.

BRs,
Rex
> 
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +
> > +		if (ret) {
> > +			if (ret == -EAGAIN)
> > +				continue;
> > +			/*
> > +			 * If we get any other error number, it doesn't
> > +			 * make any sense to keep iterating.
> > +			 */
> > +			break;
> > +		}
> > +	} while (!training_done || --max_retry);
> > +
> > +	return ret;
> > +}
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07  7:30     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07 12:46       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:46 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 15:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> > +				   struct drm_dp_aux_msg *msg)
> > +{
> > +	struct mtk_dp *mtk_dp;
> > +	bool is_read;
> > +	u8 request;
> > +	size_t accessed_bytes = 0;
> > +	int ret = 0;
> > +
> > +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> > +
> > +	if (!mtk_dp->train_info.cable_plugged_in ||
> > +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
> 
> Changing state here has no any effect, so drop this.
> 

ok, I will drop it.

> > +		return -EAGAIN;
> > +	}
> > +
> > +	switch (msg->request) {
> > +	case DP_AUX_I2C_MOT:
> > +	case DP_AUX_I2C_WRITE:
> > +	case DP_AUX_NATIVE_WRITE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> > +		request = msg->request &
> > ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> > +		is_read = false;
> > +		break;
> > +	case DP_AUX_I2C_READ:
> > +	case DP_AUX_NATIVE_READ:
> > +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> > +		request = msg->request;
> > +		is_read = true;
> > +		break;
> > +	default:
> > +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> > +			msg->request);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (msg->size == 0) {
> > +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> > +					     msg->address +
> > accessed_bytes,
> > +					     msg->buffer +
> > accessed_bytes, 0);
> > +	} else {
> > +		while (accessed_bytes < msg->size) {
> > +			size_t to_access =
> > +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> > +				      msg->size - accessed_bytes);
> > +
> > +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> > +						     is_read, request,
> > +							 msg->address +
> > accessed_bytes,
> > +							 msg->buffer +
> > accessed_bytes,
> > +							 to_access);
> > +
> > +			if (ret) {
> > +				drm_info(mtk_dp->drm_dev,
> > +					 "Failed to do AUX transfer:
> > %d\n", ret);
> > +				break;
> > +			}
> > +			accessed_bytes += to_access;
> > +		}
> > +	}
> > +
> > +	if (ret) {
> > +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> > DP_AUX_I2C_REPLY_NACK;
> > +		return ret;
> > +	}
> > +
> > +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> > +	return msg->size;
> > +}
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:46       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:46 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Tue, 2022-06-07 at 15:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> > +				   struct drm_dp_aux_msg *msg)
> > +{
> > +	struct mtk_dp *mtk_dp;
> > +	bool is_read;
> > +	u8 request;
> > +	size_t accessed_bytes = 0;
> > +	int ret = 0;
> > +
> > +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> > +
> > +	if (!mtk_dp->train_info.cable_plugged_in ||
> > +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
> 
> Changing state here has no any effect, so drop this.
> 

ok, I will drop it.

> > +		return -EAGAIN;
> > +	}
> > +
> > +	switch (msg->request) {
> > +	case DP_AUX_I2C_MOT:
> > +	case DP_AUX_I2C_WRITE:
> > +	case DP_AUX_NATIVE_WRITE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> > +		request = msg->request &
> > ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> > +		is_read = false;
> > +		break;
> > +	case DP_AUX_I2C_READ:
> > +	case DP_AUX_NATIVE_READ:
> > +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> > +		request = msg->request;
> > +		is_read = true;
> > +		break;
> > +	default:
> > +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> > +			msg->request);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (msg->size == 0) {
> > +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> > +					     msg->address +
> > accessed_bytes,
> > +					     msg->buffer +
> > accessed_bytes, 0);
> > +	} else {
> > +		while (accessed_bytes < msg->size) {
> > +			size_t to_access =
> > +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> > +				      msg->size - accessed_bytes);
> > +
> > +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> > +						     is_read, request,
> > +							 msg->address +
> > accessed_bytes,
> > +							 msg->buffer +
> > accessed_bytes,
> > +							 to_access);
> > +
> > +			if (ret) {
> > +				drm_info(mtk_dp->drm_dev,
> > +					 "Failed to do AUX transfer:
> > %d\n", ret);
> > +				break;
> > +			}
> > +			accessed_bytes += to_access;
> > +		}
> > +	}
> > +
> > +	if (ret) {
> > +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> > DP_AUX_I2C_REPLY_NACK;
> > +		return ret;
> > +	}
> > +
> > +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> > +	return msg->size;
> > +}
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:46       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:46 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 15:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> > +				   struct drm_dp_aux_msg *msg)
> > +{
> > +	struct mtk_dp *mtk_dp;
> > +	bool is_read;
> > +	u8 request;
> > +	size_t accessed_bytes = 0;
> > +	int ret = 0;
> > +
> > +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> > +
> > +	if (!mtk_dp->train_info.cable_plugged_in ||
> > +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
> 
> Changing state here has no any effect, so drop this.
> 

ok, I will drop it.

> > +		return -EAGAIN;
> > +	}
> > +
> > +	switch (msg->request) {
> > +	case DP_AUX_I2C_MOT:
> > +	case DP_AUX_I2C_WRITE:
> > +	case DP_AUX_NATIVE_WRITE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> > +		request = msg->request &
> > ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> > +		is_read = false;
> > +		break;
> > +	case DP_AUX_I2C_READ:
> > +	case DP_AUX_NATIVE_READ:
> > +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> > +		request = msg->request;
> > +		is_read = true;
> > +		break;
> > +	default:
> > +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> > +			msg->request);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (msg->size == 0) {
> > +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> > +					     msg->address +
> > accessed_bytes,
> > +					     msg->buffer +
> > accessed_bytes, 0);
> > +	} else {
> > +		while (accessed_bytes < msg->size) {
> > +			size_t to_access =
> > +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> > +				      msg->size - accessed_bytes);
> > +
> > +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> > +						     is_read, request,
> > +							 msg->address +
> > accessed_bytes,
> > +							 msg->buffer +
> > accessed_bytes,
> > +							 to_access);
> > +
> > +			if (ret) {
> > +				drm_info(mtk_dp->drm_dev,
> > +					 "Failed to do AUX transfer:
> > %d\n", ret);
> > +				break;
> > +			}
> > +			accessed_bytes += to_access;
> > +		}
> > +	}
> > +
> > +	if (ret) {
> > +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> > DP_AUX_I2C_REPLY_NACK;
> > +		return ret;
> > +	}
> > +
> > +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> > +	return msg->size;
> > +}
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:46       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:46 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 15:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> > +				   struct drm_dp_aux_msg *msg)
> > +{
> > +	struct mtk_dp *mtk_dp;
> > +	bool is_read;
> > +	u8 request;
> > +	size_t accessed_bytes = 0;
> > +	int ret = 0;
> > +
> > +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> > +
> > +	if (!mtk_dp->train_info.cable_plugged_in ||
> > +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
> 
> Changing state here has no any effect, so drop this.
> 

ok, I will drop it.

> > +		return -EAGAIN;
> > +	}
> > +
> > +	switch (msg->request) {
> > +	case DP_AUX_I2C_MOT:
> > +	case DP_AUX_I2C_WRITE:
> > +	case DP_AUX_NATIVE_WRITE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> > +		request = msg->request &
> > ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> > +		is_read = false;
> > +		break;
> > +	case DP_AUX_I2C_READ:
> > +	case DP_AUX_NATIVE_READ:
> > +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> > +		request = msg->request;
> > +		is_read = true;
> > +		break;
> > +	default:
> > +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> > +			msg->request);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (msg->size == 0) {
> > +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> > +					     msg->address +
> > accessed_bytes,
> > +					     msg->buffer +
> > accessed_bytes, 0);
> > +	} else {
> > +		while (accessed_bytes < msg->size) {
> > +			size_t to_access =
> > +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> > +				      msg->size - accessed_bytes);
> > +
> > +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> > +						     is_read, request,
> > +							 msg->address +
> > accessed_bytes,
> > +							 msg->buffer +
> > accessed_bytes,
> > +							 to_access);
> > +
> > +			if (ret) {
> > +				drm_info(mtk_dp->drm_dev,
> > +					 "Failed to do AUX transfer:
> > %d\n", ret);
> > +				break;
> > +			}
> > +			accessed_bytes += to_access;
> > +		}
> > +	}
> > +
> > +	if (ret) {
> > +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> > DP_AUX_I2C_REPLY_NACK;
> > +		return ret;
> > +	}
> > +
> > +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> > +	return msg->size;
> > +}
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:46       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:46 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 15:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> > +				   struct drm_dp_aux_msg *msg)
> > +{
> > +	struct mtk_dp *mtk_dp;
> > +	bool is_read;
> > +	u8 request;
> > +	size_t accessed_bytes = 0;
> > +	int ret = 0;
> > +
> > +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> > +
> > +	if (!mtk_dp->train_info.cable_plugged_in ||
> > +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
> 
> Changing state here has no any effect, so drop this.
> 

ok, I will drop it.

> > +		return -EAGAIN;
> > +	}
> > +
> > +	switch (msg->request) {
> > +	case DP_AUX_I2C_MOT:
> > +	case DP_AUX_I2C_WRITE:
> > +	case DP_AUX_NATIVE_WRITE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> > +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> > +		request = msg->request &
> > ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> > +		is_read = false;
> > +		break;
> > +	case DP_AUX_I2C_READ:
> > +	case DP_AUX_NATIVE_READ:
> > +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> > +		request = msg->request;
> > +		is_read = true;
> > +		break;
> > +	default:
> > +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> > +			msg->request);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (msg->size == 0) {
> > +		ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> > +					     msg->address +
> > accessed_bytes,
> > +					     msg->buffer +
> > accessed_bytes, 0);
> > +	} else {
> > +		while (accessed_bytes < msg->size) {
> > +			size_t to_access =
> > +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> > +				      msg->size - accessed_bytes);
> > +
> > +			ret = mtk_dp_aux_do_transfer(mtk_dp,
> > +						     is_read, request,
> > +							 msg->address +
> > accessed_bytes,
> > +							 msg->buffer +
> > accessed_bytes,
> > +							 to_access);
> > +
> > +			if (ret) {
> > +				drm_info(mtk_dp->drm_dev,
> > +					 "Failed to do AUX transfer:
> > %d\n", ret);
> > +				break;
> > +			}
> > +			accessed_bytes += to_access;
> > +		}
> > +	}
> > +
> > +	if (ret) {
> > +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> > DP_AUX_I2C_REPLY_NACK;
> > +		return ret;
> > +	}
> > +
> > +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> > +	return msg->size;
> > +}
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07  8:12     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-07 12:55       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:55 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 16:12 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret = 0;
> > +	u8 lane_count;
> > +	u8 link_rate;
> > +	u8 train_limit;
> > +	u8 max_link_rate;
> > +	u8 plug_wait;
> > +
> > +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> > 0;
> > +	     --plug_wait)
> > +		/* Avoid short pulses on the HPD isr */
> > +		usleep_range(1000, 5000);
> > +	if (plug_wait == 0) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 

ok, I will do this.

> > +		return -ENODEV;
> > +	}
> > +
> > +	link_rate = mtk_dp->rx_cap[1];
> > +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> > +
> > +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> > link_rate);
> > +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> > lane_count);
> > +	link_rate = mtk_dp->train_info.link_rate;
> > +	lane_count = mtk_dp->train_info.lane_count;
> > +
> > +	switch (link_rate) {
> > +	case MTK_DP_LINKRATE_RBR:
> > +	case MTK_DP_LINKRATE_HBR:
> > +	case MTK_DP_LINKRATE_HBR2:
> > +	case MTK_DP_LINKRATE_HBR25:
> > +	case MTK_DP_LINKRATE_HBR3:
> > +		break;
> > +	default:
> > +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> > +		break;
> > +	};
> > +
> > +	max_link_rate = link_rate;
> > +	for (train_limit = 6; train_limit > 0; train_limit--) {
> > +		mtk_dp->train_info.cr_done = false;
> > +		mtk_dp->train_info.eq_done = false;
> > +
> > +		mtk_dp_train_change_mode(mtk_dp);
> > +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> > +		if (ret)
> > +			return ret;
> > +
> > +		if (!mtk_dp->train_info.cr_done) {
> > +			switch (link_rate) {
> > +			case MTK_DP_LINKRATE_RBR:
> > +				lane_count = lane_count / 2;
> > +				link_rate = max_link_rate;
> > +				if (lane_count == 0) {
> > +					mtk_dp->train_state =
> > +						MTK_DP_TRAIN_STATE_DPID
> > LE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 
> Regards,
> CK
> 

ok.

> > +					return -EIO;
> > +				}
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR:
> > +				link_rate = MTK_DP_LINKRATE_RBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR2:
> > +				link_rate = MTK_DP_LINKRATE_HBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR3:
> > +				link_rate = MTK_DP_LINKRATE_HBR2;
> > +				break;
> > +			default:
> > +				return -EINVAL;
> > +			};
> > +		} else if (!mtk_dp->train_info.eq_done) {
> > +			if (lane_count == 0)
> > +				return -EIO;
> > +
> > +			lane_count /= 2;
> > +		} else {
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (train_limit == 0)
> > +		return -ETIMEDOUT;
> > +
> > +	return 0;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:55       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:55 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Tue, 2022-06-07 at 16:12 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret = 0;
> > +	u8 lane_count;
> > +	u8 link_rate;
> > +	u8 train_limit;
> > +	u8 max_link_rate;
> > +	u8 plug_wait;
> > +
> > +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> > 0;
> > +	     --plug_wait)
> > +		/* Avoid short pulses on the HPD isr */
> > +		usleep_range(1000, 5000);
> > +	if (plug_wait == 0) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 

ok, I will do this.

> > +		return -ENODEV;
> > +	}
> > +
> > +	link_rate = mtk_dp->rx_cap[1];
> > +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> > +
> > +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> > link_rate);
> > +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> > lane_count);
> > +	link_rate = mtk_dp->train_info.link_rate;
> > +	lane_count = mtk_dp->train_info.lane_count;
> > +
> > +	switch (link_rate) {
> > +	case MTK_DP_LINKRATE_RBR:
> > +	case MTK_DP_LINKRATE_HBR:
> > +	case MTK_DP_LINKRATE_HBR2:
> > +	case MTK_DP_LINKRATE_HBR25:
> > +	case MTK_DP_LINKRATE_HBR3:
> > +		break;
> > +	default:
> > +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> > +		break;
> > +	};
> > +
> > +	max_link_rate = link_rate;
> > +	for (train_limit = 6; train_limit > 0; train_limit--) {
> > +		mtk_dp->train_info.cr_done = false;
> > +		mtk_dp->train_info.eq_done = false;
> > +
> > +		mtk_dp_train_change_mode(mtk_dp);
> > +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> > +		if (ret)
> > +			return ret;
> > +
> > +		if (!mtk_dp->train_info.cr_done) {
> > +			switch (link_rate) {
> > +			case MTK_DP_LINKRATE_RBR:
> > +				lane_count = lane_count / 2;
> > +				link_rate = max_link_rate;
> > +				if (lane_count == 0) {
> > +					mtk_dp->train_state =
> > +						MTK_DP_TRAIN_STATE_DPID
> > LE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 
> Regards,
> CK
> 

ok.

> > +					return -EIO;
> > +				}
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR:
> > +				link_rate = MTK_DP_LINKRATE_RBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR2:
> > +				link_rate = MTK_DP_LINKRATE_HBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR3:
> > +				link_rate = MTK_DP_LINKRATE_HBR2;
> > +				break;
> > +			default:
> > +				return -EINVAL;
> > +			};
> > +		} else if (!mtk_dp->train_info.eq_done) {
> > +			if (lane_count == 0)
> > +				return -EIO;
> > +
> > +			lane_count /= 2;
> > +		} else {
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (train_limit == 0)
> > +		return -ETIMEDOUT;
> > +
> > +	return 0;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:55       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:55 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 16:12 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret = 0;
> > +	u8 lane_count;
> > +	u8 link_rate;
> > +	u8 train_limit;
> > +	u8 max_link_rate;
> > +	u8 plug_wait;
> > +
> > +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> > 0;
> > +	     --plug_wait)
> > +		/* Avoid short pulses on the HPD isr */
> > +		usleep_range(1000, 5000);
> > +	if (plug_wait == 0) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 

ok, I will do this.

> > +		return -ENODEV;
> > +	}
> > +
> > +	link_rate = mtk_dp->rx_cap[1];
> > +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> > +
> > +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> > link_rate);
> > +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> > lane_count);
> > +	link_rate = mtk_dp->train_info.link_rate;
> > +	lane_count = mtk_dp->train_info.lane_count;
> > +
> > +	switch (link_rate) {
> > +	case MTK_DP_LINKRATE_RBR:
> > +	case MTK_DP_LINKRATE_HBR:
> > +	case MTK_DP_LINKRATE_HBR2:
> > +	case MTK_DP_LINKRATE_HBR25:
> > +	case MTK_DP_LINKRATE_HBR3:
> > +		break;
> > +	default:
> > +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> > +		break;
> > +	};
> > +
> > +	max_link_rate = link_rate;
> > +	for (train_limit = 6; train_limit > 0; train_limit--) {
> > +		mtk_dp->train_info.cr_done = false;
> > +		mtk_dp->train_info.eq_done = false;
> > +
> > +		mtk_dp_train_change_mode(mtk_dp);
> > +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> > +		if (ret)
> > +			return ret;
> > +
> > +		if (!mtk_dp->train_info.cr_done) {
> > +			switch (link_rate) {
> > +			case MTK_DP_LINKRATE_RBR:
> > +				lane_count = lane_count / 2;
> > +				link_rate = max_link_rate;
> > +				if (lane_count == 0) {
> > +					mtk_dp->train_state =
> > +						MTK_DP_TRAIN_STATE_DPID
> > LE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 
> Regards,
> CK
> 

ok.

> > +					return -EIO;
> > +				}
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR:
> > +				link_rate = MTK_DP_LINKRATE_RBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR2:
> > +				link_rate = MTK_DP_LINKRATE_HBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR3:
> > +				link_rate = MTK_DP_LINKRATE_HBR2;
> > +				break;
> > +			default:
> > +				return -EINVAL;
> > +			};
> > +		} else if (!mtk_dp->train_info.eq_done) {
> > +			if (lane_count == 0)
> > +				return -EIO;
> > +
> > +			lane_count /= 2;
> > +		} else {
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (train_limit == 0)
> > +		return -ETIMEDOUT;
> > +
> > +	return 0;
> > +}
> > +
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:55       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:55 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 16:12 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret = 0;
> > +	u8 lane_count;
> > +	u8 link_rate;
> > +	u8 train_limit;
> > +	u8 max_link_rate;
> > +	u8 plug_wait;
> > +
> > +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> > 0;
> > +	     --plug_wait)
> > +		/* Avoid short pulses on the HPD isr */
> > +		usleep_range(1000, 5000);
> > +	if (plug_wait == 0) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 

ok, I will do this.

> > +		return -ENODEV;
> > +	}
> > +
> > +	link_rate = mtk_dp->rx_cap[1];
> > +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> > +
> > +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> > link_rate);
> > +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> > lane_count);
> > +	link_rate = mtk_dp->train_info.link_rate;
> > +	lane_count = mtk_dp->train_info.lane_count;
> > +
> > +	switch (link_rate) {
> > +	case MTK_DP_LINKRATE_RBR:
> > +	case MTK_DP_LINKRATE_HBR:
> > +	case MTK_DP_LINKRATE_HBR2:
> > +	case MTK_DP_LINKRATE_HBR25:
> > +	case MTK_DP_LINKRATE_HBR3:
> > +		break;
> > +	default:
> > +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> > +		break;
> > +	};
> > +
> > +	max_link_rate = link_rate;
> > +	for (train_limit = 6; train_limit > 0; train_limit--) {
> > +		mtk_dp->train_info.cr_done = false;
> > +		mtk_dp->train_info.eq_done = false;
> > +
> > +		mtk_dp_train_change_mode(mtk_dp);
> > +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> > +		if (ret)
> > +			return ret;
> > +
> > +		if (!mtk_dp->train_info.cr_done) {
> > +			switch (link_rate) {
> > +			case MTK_DP_LINKRATE_RBR:
> > +				lane_count = lane_count / 2;
> > +				link_rate = max_link_rate;
> > +				if (lane_count == 0) {
> > +					mtk_dp->train_state =
> > +						MTK_DP_TRAIN_STATE_DPID
> > LE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 
> Regards,
> CK
> 

ok.

> > +					return -EIO;
> > +				}
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR:
> > +				link_rate = MTK_DP_LINKRATE_RBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR2:
> > +				link_rate = MTK_DP_LINKRATE_HBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR3:
> > +				link_rate = MTK_DP_LINKRATE_HBR2;
> > +				break;
> > +			default:
> > +				return -EINVAL;
> > +			};
> > +		} else if (!mtk_dp->train_info.eq_done) {
> > +			if (lane_count == 0)
> > +				return -EIO;
> > +
> > +			lane_count /= 2;
> > +		} else {
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (train_limit == 0)
> > +		return -ETIMEDOUT;
> > +
> > +	return 0;
> > +}
> > +
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-07 12:55       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-07 12:55 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 16:12 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_train_start(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret = 0;
> > +	u8 lane_count;
> > +	u8 link_rate;
> > +	u8 train_limit;
> > +	u8 max_link_rate;
> > +	u8 plug_wait;
> > +
> > +	for (plug_wait = 7; !mtk_dp_plug_state(mtk_dp) && plug_wait >
> > 0;
> > +	     --plug_wait)
> > +		/* Avoid short pulses on the HPD isr */
> > +		usleep_range(1000, 5000);
> > +	if (plug_wait == 0) {
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 

ok, I will do this.

> > +		return -ENODEV;
> > +	}
> > +
> > +	link_rate = mtk_dp->rx_cap[1];
> > +	lane_count = mtk_dp->rx_cap[2] & 0x1F;
> > +
> > +	mtk_dp->train_info.link_rate = min(mtk_dp->max_linkrate,
> > link_rate);
> > +	mtk_dp->train_info.lane_count = min(mtk_dp->max_lanes,
> > lane_count);
> > +	link_rate = mtk_dp->train_info.link_rate;
> > +	lane_count = mtk_dp->train_info.lane_count;
> > +
> > +	switch (link_rate) {
> > +	case MTK_DP_LINKRATE_RBR:
> > +	case MTK_DP_LINKRATE_HBR:
> > +	case MTK_DP_LINKRATE_HBR2:
> > +	case MTK_DP_LINKRATE_HBR25:
> > +	case MTK_DP_LINKRATE_HBR3:
> > +		break;
> > +	default:
> > +		mtk_dp->train_info.link_rate = MTK_DP_LINKRATE_HBR3;
> > +		break;
> > +	};
> > +
> > +	max_link_rate = link_rate;
> > +	for (train_limit = 6; train_limit > 0; train_limit--) {
> > +		mtk_dp->train_info.cr_done = false;
> > +		mtk_dp->train_info.eq_done = false;
> > +
> > +		mtk_dp_train_change_mode(mtk_dp);
> > +		ret = mtk_dp_train_flow(mtk_dp, link_rate, lane_count);
> > +		if (ret)
> > +			return ret;
> > +
> > +		if (!mtk_dp->train_info.cr_done) {
> > +			switch (link_rate) {
> > +			case MTK_DP_LINKRATE_RBR:
> > +				lane_count = lane_count / 2;
> > +				link_rate = max_link_rate;
> > +				if (lane_count == 0) {
> > +					mtk_dp->train_state =
> > +						MTK_DP_TRAIN_STATE_DPID
> > LE;
> 
> After return, mtk_dp->train_state would be set to
> MTK_DP_TRAIN_STATE_DPIDLE, so drop this.
> 
> Regards,
> CK
> 

ok.

> > +					return -EIO;
> > +				}
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR:
> > +				link_rate = MTK_DP_LINKRATE_RBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR2:
> > +				link_rate = MTK_DP_LINKRATE_HBR;
> > +				break;
> > +			case MTK_DP_LINKRATE_HBR3:
> > +				link_rate = MTK_DP_LINKRATE_HBR2;
> > +				break;
> > +			default:
> > +				return -EINVAL;
> > +			};
> > +		} else if (!mtk_dp->train_info.eq_done) {
> > +			if (lane_count == 0)
> > +				return -EIO;
> > +
> > +			lane_count /= 2;
> > +		} else {
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (train_limit == 0)
> > +		return -ETIMEDOUT;
> > +
> > +	return 0;
> > +}
> > +
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07 12:24       ` Rex-BC Chen
                           ` (2 preceding siblings ...)
  (?)
@ 2022-06-08  2:23         ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:23 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > +{
> > > +	struct mtk_dp *mtk_dp = dev;
> > > +	int event;
> > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > +
> > > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > > :
> > > +						  connector_status_disc
> > > onnected;
> > > +
> > > +	if (event < 0)
> > 
> > event is always > 0, isn't it?
> > 
> 
> Hello CK,
> 
> ok, I will move this to dp patch.
> 
> > > +		return IRQ_HANDLED;
> > > +
> > > +	if (mtk_dp->drm_dev) {
> > > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > 
> > I think this ISR would come once. If bridge has not attached, the
> > drm
> > core would lost this event. Maybe you should enable eDP hardware
> > after
> > bridge attached or send this event when attached.
> > 
> 
> for edp patch, I will move it to (mtk_dp_bridge_attach).
> for dp patch, I will add it back.

I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
>drm_dev would not be NULL here. So we could drop this checking.

> 
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.cable_state_change) {
> > 
> > Executing this thread imply cable_state_change = true, so drop
> > cable_state_change.
> > 
> 
> In mtk_dp_hpd_isr_handler(), there is another irq
> "MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt
> to
> source device. it's not about connected status, so I think we still
> need this.

In bottom of mtk_dp_hpd_isr_handler(), the code is:

+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;

This thread is called only when return IRQ_WAKE_THREAD, and before
return IRQ_WAKE_THREAD, train_info->cable_state_change is always set to
true. So in this thread, train_info->cable_state_change must be true.

Regards,
CK

> 
> > > +		mtk_dp->train_info.cable_state_change = false;
> > > +
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > > +
> > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > 
> > I do not like two variable to present one thing. If
> > 
> > mtk_dp->train_info.cable_plugged_in = false
> > and
> > mtk_dp_plug_state(mtk_dp) = ture
> > 
> > What does this mean? I think this mean 'now' is connected because
> > cable_plugged_in is old information and mtk_dp_plug_state() is
> > current
> > information.
> > 
> > But I would like to keep cable_plugged_in and drop
> > mtk_dp_plug_state()
> > because cable_plugged_in would be changed in isr and it would be
> > the
> > same as mtk_dp_plug_state().
> > 
> > Regards,
> > CK
> > 
> 
> ok, I will drop this.
> 
> BRs,
> Rex
> 
> > > +			mtk_dp_video_mute(mtk_dp, true);
> > > +
> > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > +			if (mtk_dp->has_fec)
> > > +				mtk_dp_fec_enable(mtk_dp, false);
> > > +
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > > +					   DP_PWR_STATE_MASK);
> > > +		} else {
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > > NE,
> > > +					   DP_PWR_STATE_MASK);
> > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > > +			mtk_dp->train_info.link_rate =
> > > +				min_t(int, mtk_dp->max_linkrate,
> > > +				      buf[mtk_dp->max_linkrate]);
> > > +			mtk_dp->train_info.lane_count =
> > > +				min_t(int, mtk_dp->max_lanes,
> > > +				      drm_dp_max_lane_count(buf));
> > > +		}
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > +	}
> > > +
> > > +	return IRQ_HANDLED;
> > > +}
> > > +
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  2:23         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:23 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > +{
> > > +	struct mtk_dp *mtk_dp = dev;
> > > +	int event;
> > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > +
> > > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > > :
> > > +						  connector_status_disc
> > > onnected;
> > > +
> > > +	if (event < 0)
> > 
> > event is always > 0, isn't it?
> > 
> 
> Hello CK,
> 
> ok, I will move this to dp patch.
> 
> > > +		return IRQ_HANDLED;
> > > +
> > > +	if (mtk_dp->drm_dev) {
> > > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > 
> > I think this ISR would come once. If bridge has not attached, the
> > drm
> > core would lost this event. Maybe you should enable eDP hardware
> > after
> > bridge attached or send this event when attached.
> > 
> 
> for edp patch, I will move it to (mtk_dp_bridge_attach).
> for dp patch, I will add it back.

I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
>drm_dev would not be NULL here. So we could drop this checking.

> 
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.cable_state_change) {
> > 
> > Executing this thread imply cable_state_change = true, so drop
> > cable_state_change.
> > 
> 
> In mtk_dp_hpd_isr_handler(), there is another irq
> "MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt
> to
> source device. it's not about connected status, so I think we still
> need this.

In bottom of mtk_dp_hpd_isr_handler(), the code is:

+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;

This thread is called only when return IRQ_WAKE_THREAD, and before
return IRQ_WAKE_THREAD, train_info->cable_state_change is always set to
true. So in this thread, train_info->cable_state_change must be true.

Regards,
CK

> 
> > > +		mtk_dp->train_info.cable_state_change = false;
> > > +
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > > +
> > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > 
> > I do not like two variable to present one thing. If
> > 
> > mtk_dp->train_info.cable_plugged_in = false
> > and
> > mtk_dp_plug_state(mtk_dp) = ture
> > 
> > What does this mean? I think this mean 'now' is connected because
> > cable_plugged_in is old information and mtk_dp_plug_state() is
> > current
> > information.
> > 
> > But I would like to keep cable_plugged_in and drop
> > mtk_dp_plug_state()
> > because cable_plugged_in would be changed in isr and it would be
> > the
> > same as mtk_dp_plug_state().
> > 
> > Regards,
> > CK
> > 
> 
> ok, I will drop this.
> 
> BRs,
> Rex
> 
> > > +			mtk_dp_video_mute(mtk_dp, true);
> > > +
> > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > +			if (mtk_dp->has_fec)
> > > +				mtk_dp_fec_enable(mtk_dp, false);
> > > +
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > > +					   DP_PWR_STATE_MASK);
> > > +		} else {
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > > NE,
> > > +					   DP_PWR_STATE_MASK);
> > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > > +			mtk_dp->train_info.link_rate =
> > > +				min_t(int, mtk_dp->max_linkrate,
> > > +				      buf[mtk_dp->max_linkrate]);
> > > +			mtk_dp->train_info.lane_count =
> > > +				min_t(int, mtk_dp->max_lanes,
> > > +				      drm_dp_max_lane_count(buf));
> > > +		}
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > +	}
> > > +
> > > +	return IRQ_HANDLED;
> > > +}
> > > +
> > 
> > 
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  2:23         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:23 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > +{
> > > +	struct mtk_dp *mtk_dp = dev;
> > > +	int event;
> > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > +
> > > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > > :
> > > +						  connector_status_disc
> > > onnected;
> > > +
> > > +	if (event < 0)
> > 
> > event is always > 0, isn't it?
> > 
> 
> Hello CK,
> 
> ok, I will move this to dp patch.
> 
> > > +		return IRQ_HANDLED;
> > > +
> > > +	if (mtk_dp->drm_dev) {
> > > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > 
> > I think this ISR would come once. If bridge has not attached, the
> > drm
> > core would lost this event. Maybe you should enable eDP hardware
> > after
> > bridge attached or send this event when attached.
> > 
> 
> for edp patch, I will move it to (mtk_dp_bridge_attach).
> for dp patch, I will add it back.

I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
>drm_dev would not be NULL here. So we could drop this checking.

> 
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.cable_state_change) {
> > 
> > Executing this thread imply cable_state_change = true, so drop
> > cable_state_change.
> > 
> 
> In mtk_dp_hpd_isr_handler(), there is another irq
> "MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt
> to
> source device. it's not about connected status, so I think we still
> need this.

In bottom of mtk_dp_hpd_isr_handler(), the code is:

+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;

This thread is called only when return IRQ_WAKE_THREAD, and before
return IRQ_WAKE_THREAD, train_info->cable_state_change is always set to
true. So in this thread, train_info->cable_state_change must be true.

Regards,
CK

> 
> > > +		mtk_dp->train_info.cable_state_change = false;
> > > +
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > > +
> > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > 
> > I do not like two variable to present one thing. If
> > 
> > mtk_dp->train_info.cable_plugged_in = false
> > and
> > mtk_dp_plug_state(mtk_dp) = ture
> > 
> > What does this mean? I think this mean 'now' is connected because
> > cable_plugged_in is old information and mtk_dp_plug_state() is
> > current
> > information.
> > 
> > But I would like to keep cable_plugged_in and drop
> > mtk_dp_plug_state()
> > because cable_plugged_in would be changed in isr and it would be
> > the
> > same as mtk_dp_plug_state().
> > 
> > Regards,
> > CK
> > 
> 
> ok, I will drop this.
> 
> BRs,
> Rex
> 
> > > +			mtk_dp_video_mute(mtk_dp, true);
> > > +
> > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > +			if (mtk_dp->has_fec)
> > > +				mtk_dp_fec_enable(mtk_dp, false);
> > > +
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > > +					   DP_PWR_STATE_MASK);
> > > +		} else {
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > > NE,
> > > +					   DP_PWR_STATE_MASK);
> > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > > +			mtk_dp->train_info.link_rate =
> > > +				min_t(int, mtk_dp->max_linkrate,
> > > +				      buf[mtk_dp->max_linkrate]);
> > > +			mtk_dp->train_info.lane_count =
> > > +				min_t(int, mtk_dp->max_lanes,
> > > +				      drm_dp_max_lane_count(buf));
> > > +		}
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > +	}
> > > +
> > > +	return IRQ_HANDLED;
> > > +}
> > > +
> > 
> > 
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  2:23         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:23 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > +{
> > > +	struct mtk_dp *mtk_dp = dev;
> > > +	int event;
> > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > +
> > > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > > :
> > > +						  connector_status_disc
> > > onnected;
> > > +
> > > +	if (event < 0)
> > 
> > event is always > 0, isn't it?
> > 
> 
> Hello CK,
> 
> ok, I will move this to dp patch.
> 
> > > +		return IRQ_HANDLED;
> > > +
> > > +	if (mtk_dp->drm_dev) {
> > > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > 
> > I think this ISR would come once. If bridge has not attached, the
> > drm
> > core would lost this event. Maybe you should enable eDP hardware
> > after
> > bridge attached or send this event when attached.
> > 
> 
> for edp patch, I will move it to (mtk_dp_bridge_attach).
> for dp patch, I will add it back.

I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
>drm_dev would not be NULL here. So we could drop this checking.

> 
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.cable_state_change) {
> > 
> > Executing this thread imply cable_state_change = true, so drop
> > cable_state_change.
> > 
> 
> In mtk_dp_hpd_isr_handler(), there is another irq
> "MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt
> to
> source device. it's not about connected status, so I think we still
> need this.

In bottom of mtk_dp_hpd_isr_handler(), the code is:

+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;

This thread is called only when return IRQ_WAKE_THREAD, and before
return IRQ_WAKE_THREAD, train_info->cable_state_change is always set to
true. So in this thread, train_info->cable_state_change must be true.

Regards,
CK

> 
> > > +		mtk_dp->train_info.cable_state_change = false;
> > > +
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > > +
> > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > 
> > I do not like two variable to present one thing. If
> > 
> > mtk_dp->train_info.cable_plugged_in = false
> > and
> > mtk_dp_plug_state(mtk_dp) = ture
> > 
> > What does this mean? I think this mean 'now' is connected because
> > cable_plugged_in is old information and mtk_dp_plug_state() is
> > current
> > information.
> > 
> > But I would like to keep cable_plugged_in and drop
> > mtk_dp_plug_state()
> > because cable_plugged_in would be changed in isr and it would be
> > the
> > same as mtk_dp_plug_state().
> > 
> > Regards,
> > CK
> > 
> 
> ok, I will drop this.
> 
> BRs,
> Rex
> 
> > > +			mtk_dp_video_mute(mtk_dp, true);
> > > +
> > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > +			if (mtk_dp->has_fec)
> > > +				mtk_dp_fec_enable(mtk_dp, false);
> > > +
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > > +					   DP_PWR_STATE_MASK);
> > > +		} else {
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > > NE,
> > > +					   DP_PWR_STATE_MASK);
> > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > > +			mtk_dp->train_info.link_rate =
> > > +				min_t(int, mtk_dp->max_linkrate,
> > > +				      buf[mtk_dp->max_linkrate]);
> > > +			mtk_dp->train_info.lane_count =
> > > +				min_t(int, mtk_dp->max_lanes,
> > > +				      drm_dp_max_lane_count(buf));
> > > +		}
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > +	}
> > > +
> > > +	return IRQ_HANDLED;
> > > +}
> > > +
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  2:23         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:23 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > +{
> > > +	struct mtk_dp *mtk_dp = dev;
> > > +	int event;
> > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > +
> > > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > > :
> > > +						  connector_status_disc
> > > onnected;
> > > +
> > > +	if (event < 0)
> > 
> > event is always > 0, isn't it?
> > 
> 
> Hello CK,
> 
> ok, I will move this to dp patch.
> 
> > > +		return IRQ_HANDLED;
> > > +
> > > +	if (mtk_dp->drm_dev) {
> > > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > 
> > I think this ISR would come once. If bridge has not attached, the
> > drm
> > core would lost this event. Maybe you should enable eDP hardware
> > after
> > bridge attached or send this event when attached.
> > 
> 
> for edp patch, I will move it to (mtk_dp_bridge_attach).
> for dp patch, I will add it back.

I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
>drm_dev would not be NULL here. So we could drop this checking.

> 
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.cable_state_change) {
> > 
> > Executing this thread imply cable_state_change = true, so drop
> > cable_state_change.
> > 
> 
> In mtk_dp_hpd_isr_handler(), there is another irq
> "MTK_DP_HPD_INTERRUPT" which means the sink devices give a interrupt
> to
> source device. it's not about connected status, so I think we still
> need this.

In bottom of mtk_dp_hpd_isr_handler(), the code is:

+	train_info->cable_state_change = true;
+
+	return IRQ_WAKE_THREAD;

This thread is called only when return IRQ_WAKE_THREAD, and before
return IRQ_WAKE_THREAD, train_info->cable_state_change is always set to
true. So in this thread, train_info->cable_state_change must be true.

Regards,
CK

> 
> > > +		mtk_dp->train_info.cable_state_change = false;
> > > +
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > > +
> > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > 
> > I do not like two variable to present one thing. If
> > 
> > mtk_dp->train_info.cable_plugged_in = false
> > and
> > mtk_dp_plug_state(mtk_dp) = ture
> > 
> > What does this mean? I think this mean 'now' is connected because
> > cable_plugged_in is old information and mtk_dp_plug_state() is
> > current
> > information.
> > 
> > But I would like to keep cable_plugged_in and drop
> > mtk_dp_plug_state()
> > because cable_plugged_in would be changed in isr and it would be
> > the
> > same as mtk_dp_plug_state().
> > 
> > Regards,
> > CK
> > 
> 
> ok, I will drop this.
> 
> BRs,
> Rex
> 
> > > +			mtk_dp_video_mute(mtk_dp, true);
> > > +
> > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > +			if (mtk_dp->has_fec)
> > > +				mtk_dp_fec_enable(mtk_dp, false);
> > > +
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > > +					   DP_PWR_STATE_MASK);
> > > +		} else {
> > > +			mtk_dp_update_bits(mtk_dp,
> > > MTK_DP_TOP_PWR_STATE,
> > > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > > NE,
> > > +					   DP_PWR_STATE_MASK);
> > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > > +			mtk_dp->train_info.link_rate =
> > > +				min_t(int, mtk_dp->max_linkrate,
> > > +				      buf[mtk_dp->max_linkrate]);
> > > +			mtk_dp->train_info.lane_count =
> > > +				min_t(int, mtk_dp->max_lanes,
> > > +				      drm_dp_max_lane_count(buf));
> > > +		}
> > > +	}
> > > +
> > > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > +	}
> > > +
> > > +	return IRQ_HANDLED;
> > > +}
> > > +
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07 12:44       ` Rex-BC Chen
                           ` (2 preceding siblings ...)
  (?)
@ 2022-06-08  2:44         ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > +{
> > > +	bool training_done = false;
> > > +	short max_retry = 50;
> > > +	int ret = 0;
> > > +
> > > +	do {
> > > +		switch (mtk_dp->train_state) {
> > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > 
> > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > even
> > though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> > If
> > HPD ISR is not redundant, create a new state
> > MTK_DP_TRAIN_STATE_NONE
> > for init state.
> > 
> 
> Hello CK,
> 
> I think we don't need MTK_DP_TRAIN_STATE_NONE.
> Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state change
in HPD thread.

> 
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > > +				mtk_dp->train_info.check_cap_count = 0;
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > +			} else {
> > > +				mtk_dp->train_info.check_cap_count++;
> > > +
> > > +				if (mtk_dp->train_info.check_cap_count
> > > > 
> > > 
> > > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > > ) {
> > > +					mtk_dp-
> > > > train_info.check_cap_count = 0;
> > > 
> > > +					mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +					ret = -ETIMEDOUT;
> > > +				}
> > > +			}
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > 
> > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > 
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > +			ret = mtk_dp_train_start(mtk_dp);
> > > +			if (ret == 0) {
> > > +				mtk_dp_video_mute(mtk_dp, true);
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_NORMAL;
> > > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > > has_fec);
> > > 
> > > +			} else if (ret != -EAGAIN) {
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +			}
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			training_done = true;
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > 
> > When would this case happen?
> > 
> > Regards,
> > CK
> 
> Yes, if it's disconnected if we are still training for dp.
> or failed to training min spec RBR.

I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it would
jump out of this loop and would not get into this loop, so this case
would never get in. This is redundant, so remove this.

Regards,
CK

> 
> BRs,
> Rex
> > 
> > > +			break;
> > > +		default:
> > > +			break;
> > > +		}
> > > +
> > > +		if (ret) {
> > > +			if (ret == -EAGAIN)
> > > +				continue;
> > > +			/*
> > > +			 * If we get any other error number, it doesn't
> > > +			 * make any sense to keep iterating.
> > > +			 */
> > > +			break;
> > > +		}
> > > +	} while (!training_done || --max_retry);
> > > +
> > > +	return ret;
> > > +}
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  2:44         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > +{
> > > +	bool training_done = false;
> > > +	short max_retry = 50;
> > > +	int ret = 0;
> > > +
> > > +	do {
> > > +		switch (mtk_dp->train_state) {
> > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > 
> > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > even
> > though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> > If
> > HPD ISR is not redundant, create a new state
> > MTK_DP_TRAIN_STATE_NONE
> > for init state.
> > 
> 
> Hello CK,
> 
> I think we don't need MTK_DP_TRAIN_STATE_NONE.
> Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state change
in HPD thread.

> 
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > > +				mtk_dp->train_info.check_cap_count = 0;
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > +			} else {
> > > +				mtk_dp->train_info.check_cap_count++;
> > > +
> > > +				if (mtk_dp->train_info.check_cap_count
> > > > 
> > > 
> > > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > > ) {
> > > +					mtk_dp-
> > > > train_info.check_cap_count = 0;
> > > 
> > > +					mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +					ret = -ETIMEDOUT;
> > > +				}
> > > +			}
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > 
> > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > 
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > +			ret = mtk_dp_train_start(mtk_dp);
> > > +			if (ret == 0) {
> > > +				mtk_dp_video_mute(mtk_dp, true);
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_NORMAL;
> > > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > > has_fec);
> > > 
> > > +			} else if (ret != -EAGAIN) {
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +			}
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			training_done = true;
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > 
> > When would this case happen?
> > 
> > Regards,
> > CK
> 
> Yes, if it's disconnected if we are still training for dp.
> or failed to training min spec RBR.

I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it would
jump out of this loop and would not get into this loop, so this case
would never get in. This is redundant, so remove this.

Regards,
CK

> 
> BRs,
> Rex
> > 
> > > +			break;
> > > +		default:
> > > +			break;
> > > +		}
> > > +
> > > +		if (ret) {
> > > +			if (ret == -EAGAIN)
> > > +				continue;
> > > +			/*
> > > +			 * If we get any other error number, it doesn't
> > > +			 * make any sense to keep iterating.
> > > +			 */
> > > +			break;
> > > +		}
> > > +	} while (!training_done || --max_retry);
> > > +
> > > +	return ret;
> > > +}
> > 
> > 
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  2:44         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > +{
> > > +	bool training_done = false;
> > > +	short max_retry = 50;
> > > +	int ret = 0;
> > > +
> > > +	do {
> > > +		switch (mtk_dp->train_state) {
> > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > 
> > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > even
> > though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> > If
> > HPD ISR is not redundant, create a new state
> > MTK_DP_TRAIN_STATE_NONE
> > for init state.
> > 
> 
> Hello CK,
> 
> I think we don't need MTK_DP_TRAIN_STATE_NONE.
> Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state change
in HPD thread.

> 
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > > +				mtk_dp->train_info.check_cap_count = 0;
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > +			} else {
> > > +				mtk_dp->train_info.check_cap_count++;
> > > +
> > > +				if (mtk_dp->train_info.check_cap_count
> > > > 
> > > 
> > > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > > ) {
> > > +					mtk_dp-
> > > > train_info.check_cap_count = 0;
> > > 
> > > +					mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +					ret = -ETIMEDOUT;
> > > +				}
> > > +			}
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > 
> > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > 
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > +			ret = mtk_dp_train_start(mtk_dp);
> > > +			if (ret == 0) {
> > > +				mtk_dp_video_mute(mtk_dp, true);
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_NORMAL;
> > > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > > has_fec);
> > > 
> > > +			} else if (ret != -EAGAIN) {
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +			}
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			training_done = true;
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > 
> > When would this case happen?
> > 
> > Regards,
> > CK
> 
> Yes, if it's disconnected if we are still training for dp.
> or failed to training min spec RBR.

I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it would
jump out of this loop and would not get into this loop, so this case
would never get in. This is redundant, so remove this.

Regards,
CK

> 
> BRs,
> Rex
> > 
> > > +			break;
> > > +		default:
> > > +			break;
> > > +		}
> > > +
> > > +		if (ret) {
> > > +			if (ret == -EAGAIN)
> > > +				continue;
> > > +			/*
> > > +			 * If we get any other error number, it doesn't
> > > +			 * make any sense to keep iterating.
> > > +			 */
> > > +			break;
> > > +		}
> > > +	} while (!training_done || --max_retry);
> > > +
> > > +	return ret;
> > > +}
> > 
> > 
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  2:44         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > +{
> > > +	bool training_done = false;
> > > +	short max_retry = 50;
> > > +	int ret = 0;
> > > +
> > > +	do {
> > > +		switch (mtk_dp->train_state) {
> > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > 
> > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > even
> > though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> > If
> > HPD ISR is not redundant, create a new state
> > MTK_DP_TRAIN_STATE_NONE
> > for init state.
> > 
> 
> Hello CK,
> 
> I think we don't need MTK_DP_TRAIN_STATE_NONE.
> Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state change
in HPD thread.

> 
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > > +				mtk_dp->train_info.check_cap_count = 0;
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > +			} else {
> > > +				mtk_dp->train_info.check_cap_count++;
> > > +
> > > +				if (mtk_dp->train_info.check_cap_count
> > > > 
> > > 
> > > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > > ) {
> > > +					mtk_dp-
> > > > train_info.check_cap_count = 0;
> > > 
> > > +					mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +					ret = -ETIMEDOUT;
> > > +				}
> > > +			}
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > 
> > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > 
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > +			ret = mtk_dp_train_start(mtk_dp);
> > > +			if (ret == 0) {
> > > +				mtk_dp_video_mute(mtk_dp, true);
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_NORMAL;
> > > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > > has_fec);
> > > 
> > > +			} else if (ret != -EAGAIN) {
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +			}
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			training_done = true;
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > 
> > When would this case happen?
> > 
> > Regards,
> > CK
> 
> Yes, if it's disconnected if we are still training for dp.
> or failed to training min spec RBR.

I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it would
jump out of this loop and would not get into this loop, so this case
would never get in. This is redundant, so remove this.

Regards,
CK

> 
> BRs,
> Rex
> > 
> > > +			break;
> > > +		default:
> > > +			break;
> > > +		}
> > > +
> > > +		if (ret) {
> > > +			if (ret == -EAGAIN)
> > > +				continue;
> > > +			/*
> > > +			 * If we get any other error number, it doesn't
> > > +			 * make any sense to keep iterating.
> > > +			 */
> > > +			break;
> > > +		}
> > > +	} while (!training_done || --max_retry);
> > > +
> > > +	return ret;
> > > +}
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  2:44         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  2:44 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > +{
> > > +	bool training_done = false;
> > > +	short max_retry = 50;
> > > +	int ret = 0;
> > > +
> > > +	do {
> > > +		switch (mtk_dp->train_state) {
> > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > 
> > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > even
> > though HPD ISR does not exist. Does this mean HPD ISR is redundant?
> > If
> > HPD ISR is not redundant, create a new state
> > MTK_DP_TRAIN_STATE_NONE
> > for init state.
> > 
> 
> Hello CK,
> 
> I think we don't need MTK_DP_TRAIN_STATE_NONE.
> Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".

The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
change state from MTK_DP_TRAIN_STATE_STARTUP to
MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state change
in HPD thread.

> 
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > +			if (mtk_dp_parse_capabilities(mtk_dp)) {
> > > +				mtk_dp->train_info.check_cap_count = 0;
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > +			} else {
> > > +				mtk_dp->train_info.check_cap_count++;
> > > +
> > > +				if (mtk_dp->train_info.check_cap_count
> > > > 
> > > 
> > > +				    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT
> > > ) {
> > > +					mtk_dp-
> > > > train_info.check_cap_count = 0;
> > > 
> > > +					mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +					ret = -ETIMEDOUT;
> > > +				}
> > > +			}
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > 
> > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > 
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_TRAINING;
> > > +			break;
> > > +
> > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > +			ret = mtk_dp_train_start(mtk_dp);
> > > +			if (ret == 0) {
> > > +				mtk_dp_video_mute(mtk_dp, true);
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_NORMAL;
> > > +				mtk_dp_fec_enable(mtk_dp, mtk_dp-
> > > > has_fec);
> > > 
> > > +			} else if (ret != -EAGAIN) {
> > > +				mtk_dp->train_state =
> > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > +			}
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > +			mtk_dp_state_handler(mtk_dp);
> > > +			training_done = true;
> > > +			break;
> > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > 
> > When would this case happen?
> > 
> > Regards,
> > CK
> 
> Yes, if it's disconnected if we are still training for dp.
> or failed to training min spec RBR.

I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it would
jump out of this loop and would not get into this loop, so this case
would never get in. This is redundant, so remove this.

Regards,
CK

> 
> BRs,
> Rex
> > 
> > > +			break;
> > > +		default:
> > > +			break;
> > > +		}
> > > +
> > > +		if (ret) {
> > > +			if (ret == -EAGAIN)
> > > +				continue;
> > > +			/*
> > > +			 * If we get any other error number, it doesn't
> > > +			 * make any sense to keep iterating.
> > > +			 */
> > > +			break;
> > > +		}
> > > +	} while (!training_done || --max_retry);
> > > +
> > > +	return ret;
> > > +}
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-08  8:30     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> +{
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +	u8 val;
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	if (!mtk_dp_plug_state(mtk_dp))
> +		return false;
> +
> +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> DP_SET_POWER_D0);
> +	/* Wait for power on */
> +	usleep_range(2000, 5000);
> +
> +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +
> +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> sizeof(buf)));

sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so

drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);


> +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> DP_TRAINING_AUX_RD_MASK;
> +
> +	train_info->link_rate =
> +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> >max_linkrate]);
> +	train_info->lane_count =
> +		min_t(int, mtk_dp->max_lanes,
> drm_dp_max_lane_count(buf));
> +
> +	train_info->tps3 = drm_dp_tps3_supported(buf);
> +	train_info->tps4 = drm_dp_tps4_supported(buf);
> +
> +	train_info->sink_ssc =
> +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> +
> +	train_info->sink_ssc = false;

What does these two statement do?

Regards,
CK

> +
> +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> +	if (val & DP_MST_CAP) {
> +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> +		drm_dp_dpcd_readb(&mtk_dp->aux,
> +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> &val);
> +		if (val)
> +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> _ESI0,
> +					   val);
> +	}
> +
> +	return true;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:30     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> +{
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +	u8 val;
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	if (!mtk_dp_plug_state(mtk_dp))
> +		return false;
> +
> +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> DP_SET_POWER_D0);
> +	/* Wait for power on */
> +	usleep_range(2000, 5000);
> +
> +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +
> +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> sizeof(buf)));

sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so

drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);


> +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> DP_TRAINING_AUX_RD_MASK;
> +
> +	train_info->link_rate =
> +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> >max_linkrate]);
> +	train_info->lane_count =
> +		min_t(int, mtk_dp->max_lanes,
> drm_dp_max_lane_count(buf));
> +
> +	train_info->tps3 = drm_dp_tps3_supported(buf);
> +	train_info->tps4 = drm_dp_tps4_supported(buf);
> +
> +	train_info->sink_ssc =
> +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> +
> +	train_info->sink_ssc = false;

What does these two statement do?

Regards,
CK

> +
> +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> +	if (val & DP_MST_CAP) {
> +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> +		drm_dp_dpcd_readb(&mtk_dp->aux,
> +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> &val);
> +		if (val)
> +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> _ESI0,
> +					   val);
> +	}
> +
> +	return true;
> +}
> +


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:30     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> +{
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +	u8 val;
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	if (!mtk_dp_plug_state(mtk_dp))
> +		return false;
> +
> +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> DP_SET_POWER_D0);
> +	/* Wait for power on */
> +	usleep_range(2000, 5000);
> +
> +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +
> +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> sizeof(buf)));

sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so

drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);


> +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> DP_TRAINING_AUX_RD_MASK;
> +
> +	train_info->link_rate =
> +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> >max_linkrate]);
> +	train_info->lane_count =
> +		min_t(int, mtk_dp->max_lanes,
> drm_dp_max_lane_count(buf));
> +
> +	train_info->tps3 = drm_dp_tps3_supported(buf);
> +	train_info->tps4 = drm_dp_tps4_supported(buf);
> +
> +	train_info->sink_ssc =
> +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> +
> +	train_info->sink_ssc = false;

What does these two statement do?

Regards,
CK

> +
> +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> +	if (val & DP_MST_CAP) {
> +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> +		drm_dp_dpcd_readb(&mtk_dp->aux,
> +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> &val);
> +		if (val)
> +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> _ESI0,
> +					   val);
> +	}
> +
> +	return true;
> +}
> +


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:30     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> +{
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +	u8 val;
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	if (!mtk_dp_plug_state(mtk_dp))
> +		return false;
> +
> +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> DP_SET_POWER_D0);
> +	/* Wait for power on */
> +	usleep_range(2000, 5000);
> +
> +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +
> +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> sizeof(buf)));

sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so

drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);


> +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> DP_TRAINING_AUX_RD_MASK;
> +
> +	train_info->link_rate =
> +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> >max_linkrate]);
> +	train_info->lane_count =
> +		min_t(int, mtk_dp->max_lanes,
> drm_dp_max_lane_count(buf));
> +
> +	train_info->tps3 = drm_dp_tps3_supported(buf);
> +	train_info->tps4 = drm_dp_tps4_supported(buf);
> +
> +	train_info->sink_ssc =
> +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> +
> +	train_info->sink_ssc = false;

What does these two statement do?

Regards,
CK

> +
> +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> +	if (val & DP_MST_CAP) {
> +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> +		drm_dp_dpcd_readb(&mtk_dp->aux,
> +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> &val);
> +		if (val)
> +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> _ESI0,
> +					   val);
> +	}
> +
> +	return true;
> +}
> +


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:30     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> +{
> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +	u8 val;
> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	if (!mtk_dp_plug_state(mtk_dp))
> +		return false;
> +
> +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> DP_SET_POWER_D0);
> +	/* Wait for power on */
> +	usleep_range(2000, 5000);
> +
> +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +
> +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> sizeof(buf)));

sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so

drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);


> +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> DP_TRAINING_AUX_RD_MASK;
> +
> +	train_info->link_rate =
> +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> >max_linkrate]);
> +	train_info->lane_count =
> +		min_t(int, mtk_dp->max_lanes,
> drm_dp_max_lane_count(buf));
> +
> +	train_info->tps3 = drm_dp_tps3_supported(buf);
> +	train_info->tps4 = drm_dp_tps4_supported(buf);
> +
> +	train_info->sink_ssc =
> +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> +
> +	train_info->sink_ssc = false;

What does these two statement do?

Regards,
CK

> +
> +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> +	if (val & DP_MST_CAP) {
> +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> +		drm_dp_dpcd_readb(&mtk_dp->aux,
> +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> &val);
> +		if (val)
> +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> _ESI0,
> +					   val);
> +	}
> +
> +	return true;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-08  2:23         ` CK Hu
                             ` (2 preceding siblings ...)
  (?)
@ 2022-06-08  8:43           ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:43 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > > +{
> > > > +	struct mtk_dp *mtk_dp = dev;
> > > > +	int event;
> > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > +
> > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > connector_status_connected
> > > > :
> > > > +						  connector_sta
> > > > tus_disc
> > > > onnected;
> > > > +
> > > > +	if (event < 0)
> > > 
> > > event is always > 0, isn't it?
> > > 
> > 
> > Hello CK,
> > 
> > ok, I will move this to dp patch.
> > 
> > > > +		return IRQ_HANDLED;
> > > > +
> > > > +	if (mtk_dp->drm_dev) {
> > > > +		dev_info(mtk_dp->dev,
> > > > "drm_helper_hpd_irq_event\n");
> > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > 
> > > I think this ISR would come once. If bridge has not attached, the
> > > drm
> > > core would lost this event. Maybe you should enable eDP hardware
> > > after
> > > bridge attached or send this event when attached.
> > > 
> > 
> > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > for dp patch, I will add it back.
> 
> I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
> If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
> > drm_dev would not be NULL here. So we could drop this checking.
> > 

Hello CK,

If we failed to setup phy(ret!=0), we alos need to deattach this
bridge.
I don't think  it's a good idea just for remove this.

> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > 
> > > Executing this thread imply cable_state_change = true, so drop
> > > cable_state_change.
> > > 
> > 
> > In mtk_dp_hpd_isr_handler(), there is another irq
> > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > interrupt
> > to
> > source device. it's not about connected status, so I think we still
> > need this.
> 
> In bottom of mtk_dp_hpd_isr_handler(), the code is:
> 
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> 
> This thread is called only when return IRQ_WAKE_THREAD, and before
> return IRQ_WAKE_THREAD, train_info->cable_state_change is always set
> to
> true. So in this thread, train_info->cable_state_change must be true.
> 

As mentioned, this irq handler function is not only for connected
status.

this could be return if this irq is interrupt from sink device.
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;

BRs,
Bo-Chen
> Regards,
> CK
> 
> > 
> > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > +
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > +
> > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > 
> > > I do not like two variable to present one thing. If
> > > 
> > > mtk_dp->train_info.cable_plugged_in = false
> > > and
> > > mtk_dp_plug_state(mtk_dp) = ture
> > > 
> > > What does this mean? I think this mean 'now' is connected because
> > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > current
> > > information.
> > > 
> > > But I would like to keep cable_plugged_in and drop
> > > mtk_dp_plug_state()
> > > because cable_plugged_in would be changed in isr and it would be
> > > the
> > > same as mtk_dp_plug_state().
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > ok, I will drop this.
> > 
> > BRs,
> > Rex
> > 
> > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > +
> > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > +			if (mtk_dp->has_fec)
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > false);
> > > > +
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +		} else {
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL_LA
> > > > NE,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > buf);
> > > > +			mtk_dp->train_info.link_rate =
> > > > +				min_t(int, mtk_dp-
> > > > >max_linkrate,
> > > > +				      buf[mtk_dp-
> > > > >max_linkrate]);
> > > > +			mtk_dp->train_info.lane_count =
> > > > +				min_t(int, mtk_dp->max_lanes,
> > > > +				      drm_dp_max_lane_count(buf
> > > > ));
> > > > +		}
> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.irq_status &
> > > > MTK_DP_HPD_INTERRUPT) {
> > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > +		mtk_dp->train_info.irq_status &=
> > > > ~MTK_DP_HPD_INTERRUPT;
> > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > +	}
> > > > +
> > > > +	return IRQ_HANDLED;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:43           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:43 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > > +{
> > > > +	struct mtk_dp *mtk_dp = dev;
> > > > +	int event;
> > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > +
> > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > connector_status_connected
> > > > :
> > > > +						  connector_sta
> > > > tus_disc
> > > > onnected;
> > > > +
> > > > +	if (event < 0)
> > > 
> > > event is always > 0, isn't it?
> > > 
> > 
> > Hello CK,
> > 
> > ok, I will move this to dp patch.
> > 
> > > > +		return IRQ_HANDLED;
> > > > +
> > > > +	if (mtk_dp->drm_dev) {
> > > > +		dev_info(mtk_dp->dev,
> > > > "drm_helper_hpd_irq_event\n");
> > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > 
> > > I think this ISR would come once. If bridge has not attached, the
> > > drm
> > > core would lost this event. Maybe you should enable eDP hardware
> > > after
> > > bridge attached or send this event when attached.
> > > 
> > 
> > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > for dp patch, I will add it back.
> 
> I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
> If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
> > drm_dev would not be NULL here. So we could drop this checking.
> > 

Hello CK,

If we failed to setup phy(ret!=0), we alos need to deattach this
bridge.
I don't think  it's a good idea just for remove this.

> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > 
> > > Executing this thread imply cable_state_change = true, so drop
> > > cable_state_change.
> > > 
> > 
> > In mtk_dp_hpd_isr_handler(), there is another irq
> > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > interrupt
> > to
> > source device. it's not about connected status, so I think we still
> > need this.
> 
> In bottom of mtk_dp_hpd_isr_handler(), the code is:
> 
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> 
> This thread is called only when return IRQ_WAKE_THREAD, and before
> return IRQ_WAKE_THREAD, train_info->cable_state_change is always set
> to
> true. So in this thread, train_info->cable_state_change must be true.
> 

As mentioned, this irq handler function is not only for connected
status.

this could be return if this irq is interrupt from sink device.
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;

BRs,
Bo-Chen
> Regards,
> CK
> 
> > 
> > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > +
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > +
> > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > 
> > > I do not like two variable to present one thing. If
> > > 
> > > mtk_dp->train_info.cable_plugged_in = false
> > > and
> > > mtk_dp_plug_state(mtk_dp) = ture
> > > 
> > > What does this mean? I think this mean 'now' is connected because
> > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > current
> > > information.
> > > 
> > > But I would like to keep cable_plugged_in and drop
> > > mtk_dp_plug_state()
> > > because cable_plugged_in would be changed in isr and it would be
> > > the
> > > same as mtk_dp_plug_state().
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > ok, I will drop this.
> > 
> > BRs,
> > Rex
> > 
> > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > +
> > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > +			if (mtk_dp->has_fec)
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > false);
> > > > +
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +		} else {
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL_LA
> > > > NE,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > buf);
> > > > +			mtk_dp->train_info.link_rate =
> > > > +				min_t(int, mtk_dp-
> > > > >max_linkrate,
> > > > +				      buf[mtk_dp-
> > > > >max_linkrate]);
> > > > +			mtk_dp->train_info.lane_count =
> > > > +				min_t(int, mtk_dp->max_lanes,
> > > > +				      drm_dp_max_lane_count(buf
> > > > ));
> > > > +		}
> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.irq_status &
> > > > MTK_DP_HPD_INTERRUPT) {
> > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > +		mtk_dp->train_info.irq_status &=
> > > > ~MTK_DP_HPD_INTERRUPT;
> > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > +	}
> > > > +
> > > > +	return IRQ_HANDLED;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:43           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:43 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > > +{
> > > > +	struct mtk_dp *mtk_dp = dev;
> > > > +	int event;
> > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > +
> > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > connector_status_connected
> > > > :
> > > > +						  connector_sta
> > > > tus_disc
> > > > onnected;
> > > > +
> > > > +	if (event < 0)
> > > 
> > > event is always > 0, isn't it?
> > > 
> > 
> > Hello CK,
> > 
> > ok, I will move this to dp patch.
> > 
> > > > +		return IRQ_HANDLED;
> > > > +
> > > > +	if (mtk_dp->drm_dev) {
> > > > +		dev_info(mtk_dp->dev,
> > > > "drm_helper_hpd_irq_event\n");
> > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > 
> > > I think this ISR would come once. If bridge has not attached, the
> > > drm
> > > core would lost this event. Maybe you should enable eDP hardware
> > > after
> > > bridge attached or send this event when attached.
> > > 
> > 
> > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > for dp patch, I will add it back.
> 
> I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
> If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
> > drm_dev would not be NULL here. So we could drop this checking.
> > 

Hello CK,

If we failed to setup phy(ret!=0), we alos need to deattach this
bridge.
I don't think  it's a good idea just for remove this.

> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > 
> > > Executing this thread imply cable_state_change = true, so drop
> > > cable_state_change.
> > > 
> > 
> > In mtk_dp_hpd_isr_handler(), there is another irq
> > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > interrupt
> > to
> > source device. it's not about connected status, so I think we still
> > need this.
> 
> In bottom of mtk_dp_hpd_isr_handler(), the code is:
> 
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> 
> This thread is called only when return IRQ_WAKE_THREAD, and before
> return IRQ_WAKE_THREAD, train_info->cable_state_change is always set
> to
> true. So in this thread, train_info->cable_state_change must be true.
> 

As mentioned, this irq handler function is not only for connected
status.

this could be return if this irq is interrupt from sink device.
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;

BRs,
Bo-Chen
> Regards,
> CK
> 
> > 
> > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > +
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > +
> > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > 
> > > I do not like two variable to present one thing. If
> > > 
> > > mtk_dp->train_info.cable_plugged_in = false
> > > and
> > > mtk_dp_plug_state(mtk_dp) = ture
> > > 
> > > What does this mean? I think this mean 'now' is connected because
> > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > current
> > > information.
> > > 
> > > But I would like to keep cable_plugged_in and drop
> > > mtk_dp_plug_state()
> > > because cable_plugged_in would be changed in isr and it would be
> > > the
> > > same as mtk_dp_plug_state().
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > ok, I will drop this.
> > 
> > BRs,
> > Rex
> > 
> > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > +
> > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > +			if (mtk_dp->has_fec)
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > false);
> > > > +
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +		} else {
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL_LA
> > > > NE,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > buf);
> > > > +			mtk_dp->train_info.link_rate =
> > > > +				min_t(int, mtk_dp-
> > > > >max_linkrate,
> > > > +				      buf[mtk_dp-
> > > > >max_linkrate]);
> > > > +			mtk_dp->train_info.lane_count =
> > > > +				min_t(int, mtk_dp->max_lanes,
> > > > +				      drm_dp_max_lane_count(buf
> > > > ));
> > > > +		}
> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.irq_status &
> > > > MTK_DP_HPD_INTERRUPT) {
> > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > +		mtk_dp->train_info.irq_status &=
> > > > ~MTK_DP_HPD_INTERRUPT;
> > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > +	}
> > > > +
> > > > +	return IRQ_HANDLED;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:43           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:43 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > > +{
> > > > +	struct mtk_dp *mtk_dp = dev;
> > > > +	int event;
> > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > +
> > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > connector_status_connected
> > > > :
> > > > +						  connector_sta
> > > > tus_disc
> > > > onnected;
> > > > +
> > > > +	if (event < 0)
> > > 
> > > event is always > 0, isn't it?
> > > 
> > 
> > Hello CK,
> > 
> > ok, I will move this to dp patch.
> > 
> > > > +		return IRQ_HANDLED;
> > > > +
> > > > +	if (mtk_dp->drm_dev) {
> > > > +		dev_info(mtk_dp->dev,
> > > > "drm_helper_hpd_irq_event\n");
> > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > 
> > > I think this ISR would come once. If bridge has not attached, the
> > > drm
> > > core would lost this event. Maybe you should enable eDP hardware
> > > after
> > > bridge attached or send this event when attached.
> > > 
> > 
> > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > for dp patch, I will add it back.
> 
> I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
> If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
> > drm_dev would not be NULL here. So we could drop this checking.
> > 

Hello CK,

If we failed to setup phy(ret!=0), we alos need to deattach this
bridge.
I don't think  it's a good idea just for remove this.

> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > 
> > > Executing this thread imply cable_state_change = true, so drop
> > > cable_state_change.
> > > 
> > 
> > In mtk_dp_hpd_isr_handler(), there is another irq
> > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > interrupt
> > to
> > source device. it's not about connected status, so I think we still
> > need this.
> 
> In bottom of mtk_dp_hpd_isr_handler(), the code is:
> 
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> 
> This thread is called only when return IRQ_WAKE_THREAD, and before
> return IRQ_WAKE_THREAD, train_info->cable_state_change is always set
> to
> true. So in this thread, train_info->cable_state_change must be true.
> 

As mentioned, this irq handler function is not only for connected
status.

this could be return if this irq is interrupt from sink device.
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;

BRs,
Bo-Chen
> Regards,
> CK
> 
> > 
> > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > +
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > +
> > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > 
> > > I do not like two variable to present one thing. If
> > > 
> > > mtk_dp->train_info.cable_plugged_in = false
> > > and
> > > mtk_dp_plug_state(mtk_dp) = ture
> > > 
> > > What does this mean? I think this mean 'now' is connected because
> > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > current
> > > information.
> > > 
> > > But I would like to keep cable_plugged_in and drop
> > > mtk_dp_plug_state()
> > > because cable_plugged_in would be changed in isr and it would be
> > > the
> > > same as mtk_dp_plug_state().
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > ok, I will drop this.
> > 
> > BRs,
> > Rex
> > 
> > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > +
> > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > +			if (mtk_dp->has_fec)
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > false);
> > > > +
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +		} else {
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL_LA
> > > > NE,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > buf);
> > > > +			mtk_dp->train_info.link_rate =
> > > > +				min_t(int, mtk_dp-
> > > > >max_linkrate,
> > > > +				      buf[mtk_dp-
> > > > >max_linkrate]);
> > > > +			mtk_dp->train_info.lane_count =
> > > > +				min_t(int, mtk_dp->max_lanes,
> > > > +				      drm_dp_max_lane_count(buf
> > > > ));
> > > > +		}
> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.irq_status &
> > > > MTK_DP_HPD_INTERRUPT) {
> > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > +		mtk_dp->train_info.irq_status &=
> > > > ~MTK_DP_HPD_INTERRUPT;
> > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > +	}
> > > > +
> > > > +	return IRQ_HANDLED;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:43           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:43 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > > > +{
> > > > +	struct mtk_dp *mtk_dp = dev;
> > > > +	int event;
> > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > +
> > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > connector_status_connected
> > > > :
> > > > +						  connector_sta
> > > > tus_disc
> > > > onnected;
> > > > +
> > > > +	if (event < 0)
> > > 
> > > event is always > 0, isn't it?
> > > 
> > 
> > Hello CK,
> > 
> > ok, I will move this to dp patch.
> > 
> > > > +		return IRQ_HANDLED;
> > > > +
> > > > +	if (mtk_dp->drm_dev) {
> > > > +		dev_info(mtk_dp->dev,
> > > > "drm_helper_hpd_irq_event\n");
> > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > 
> > > I think this ISR would come once. If bridge has not attached, the
> > > drm
> > > core would lost this event. Maybe you should enable eDP hardware
> > > after
> > > bridge attached or send this event when attached.
> > > 
> > 
> > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > for dp patch, I will add it back.
> 
> I find out that mtk_dp_poweron() is in top of mtk_dp_bridge_attach().
> If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(), mtk_dp-
> > drm_dev would not be NULL here. So we could drop this checking.
> > 

Hello CK,

If we failed to setup phy(ret!=0), we alos need to deattach this
bridge.
I don't think  it's a good idea just for remove this.

> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > 
> > > Executing this thread imply cable_state_change = true, so drop
> > > cable_state_change.
> > > 
> > 
> > In mtk_dp_hpd_isr_handler(), there is another irq
> > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > interrupt
> > to
> > source device. it's not about connected status, so I think we still
> > need this.
> 
> In bottom of mtk_dp_hpd_isr_handler(), the code is:
> 
> +	train_info->cable_state_change = true;
> +
> +	return IRQ_WAKE_THREAD;
> 
> This thread is called only when return IRQ_WAKE_THREAD, and before
> return IRQ_WAKE_THREAD, train_info->cable_state_change is always set
> to
> true. So in this thread, train_info->cable_state_change must be true.
> 

As mentioned, this irq handler function is not only for connected
status.

this could be return if this irq is interrupt from sink device.
+	if (!(train_info->irq_status &
+	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
+		return IRQ_HANDLED;

BRs,
Bo-Chen
> Regards,
> CK
> 
> > 
> > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > +
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > +
> > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > 
> > > I do not like two variable to present one thing. If
> > > 
> > > mtk_dp->train_info.cable_plugged_in = false
> > > and
> > > mtk_dp_plug_state(mtk_dp) = ture
> > > 
> > > What does this mean? I think this mean 'now' is connected because
> > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > current
> > > information.
> > > 
> > > But I would like to keep cable_plugged_in and drop
> > > mtk_dp_plug_state()
> > > because cable_plugged_in would be changed in isr and it would be
> > > the
> > > same as mtk_dp_plug_state().
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > ok, I will drop this.
> > 
> > BRs,
> > Rex
> > 
> > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > +
> > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > +			if (mtk_dp->has_fec)
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > false);
> > > > +
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +		} else {
> > > > +			mtk_dp_update_bits(mtk_dp,
> > > > MTK_DP_TOP_PWR_STATE,
> > > > +					   DP_PWR_STATE_BANDGAP
> > > > _TPLL_LA
> > > > NE,
> > > > +					   DP_PWR_STATE_MASK);
> > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > buf);
> > > > +			mtk_dp->train_info.link_rate =
> > > > +				min_t(int, mtk_dp-
> > > > >max_linkrate,
> > > > +				      buf[mtk_dp-
> > > > >max_linkrate]);
> > > > +			mtk_dp->train_info.lane_count =
> > > > +				min_t(int, mtk_dp->max_lanes,
> > > > +				      drm_dp_max_lane_count(buf
> > > > ));
> > > > +		}
> > > > +	}
> > > > +
> > > > +	if (mtk_dp->train_info.irq_status &
> > > > MTK_DP_HPD_INTERRUPT) {
> > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > +		mtk_dp->train_info.irq_status &=
> > > > ~MTK_DP_HPD_INTERRUPT;
> > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > +	}
> > > > +
> > > > +	return IRQ_HANDLED;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-08  8:45     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:45 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int
> lane_num,
> +					  int swing_val, int
> preemphasis)

The return value is never processed, so let this function to be void.

Regards,
CK

> +{
> +	int ret;
> +
> +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> +
> +	if (lane_num < 0 || lane_num > 3)

lane_num < 0 would not happen. lane_num > 3 only if device tree max
lane is wrong. So I would like to checkout max lane when parsing device
tree instead of checking here.

> +		return false;
> +
> +	dev_dbg(mtk_dp->dev,
> +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> +		swing_val, preemphasis);
> +
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> + lane_shift),
> +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> +	if (ret)
> +		return ret;
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> + lane_shift),
> +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> +
> +	return !ret;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:45     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:45 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int
> lane_num,
> +					  int swing_val, int
> preemphasis)

The return value is never processed, so let this function to be void.

Regards,
CK

> +{
> +	int ret;
> +
> +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> +
> +	if (lane_num < 0 || lane_num > 3)

lane_num < 0 would not happen. lane_num > 3 only if device tree max
lane is wrong. So I would like to checkout max lane when parsing device
tree instead of checking here.

> +		return false;
> +
> +	dev_dbg(mtk_dp->dev,
> +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> +		swing_val, preemphasis);
> +
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> + lane_shift),
> +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> +	if (ret)
> +		return ret;
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> + lane_shift),
> +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> +
> +	return !ret;
> +}
> +


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:45     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:45 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int
> lane_num,
> +					  int swing_val, int
> preemphasis)

The return value is never processed, so let this function to be void.

Regards,
CK

> +{
> +	int ret;
> +
> +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> +
> +	if (lane_num < 0 || lane_num > 3)

lane_num < 0 would not happen. lane_num > 3 only if device tree max
lane is wrong. So I would like to checkout max lane when parsing device
tree instead of checking here.

> +		return false;
> +
> +	dev_dbg(mtk_dp->dev,
> +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> +		swing_val, preemphasis);
> +
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> + lane_shift),
> +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> +	if (ret)
> +		return ret;
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> + lane_shift),
> +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> +
> +	return !ret;
> +}
> +


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:45     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:45 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int
> lane_num,
> +					  int swing_val, int
> preemphasis)

The return value is never processed, so let this function to be void.

Regards,
CK

> +{
> +	int ret;
> +
> +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> +
> +	if (lane_num < 0 || lane_num > 3)

lane_num < 0 would not happen. lane_num > 3 only if device tree max
lane is wrong. So I would like to checkout max lane when parsing device
tree instead of checking here.

> +		return false;
> +
> +	dev_dbg(mtk_dp->dev,
> +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> +		swing_val, preemphasis);
> +
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> + lane_shift),
> +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> +	if (ret)
> +		return ret;
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> + lane_shift),
> +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> +
> +	return !ret;
> +}
> +


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:45     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  8:45 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int
> lane_num,
> +					  int swing_val, int
> preemphasis)

The return value is never processed, so let this function to be void.

Regards,
CK

> +{
> +	int ret;
> +
> +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> +
> +	if (lane_num < 0 || lane_num > 3)

lane_num < 0 would not happen. lane_num > 3 only if device tree max
lane is wrong. So I would like to checkout max lane when parsing device
tree instead of checking here.

> +		return false;
> +
> +	dev_dbg(mtk_dp->dev,
> +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> +		swing_val, preemphasis);
> +
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> + lane_shift),
> +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> +	if (ret)
> +		return ret;
> +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> + lane_shift),
> +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> +
> +	return !ret;
> +}
> +


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-08  8:45     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-08  8:54       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-06-08 at 16:45 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp,
> > int
> > lane_num,
> > +					  int swing_val, int
> > preemphasis)
> 
> The return value is never processed, so let this function to be void.
> 
> Regards,
> CK
> 

Hello CK,

ok, I will drop this.
Actually, I change "mtk_dp_write", "mtk_dp_update_bits" and
"mtk_dp_bulk_16bit_write" to return void. I don't think we need to
handle the issue that we failed to set registers. If we failed to set
register, it's because hw is not enable.

Therefore, I drop this and we can reduce many lines of codes.

BRs,
Bo-Chen
> > +{
> > +	int ret;
> > +
> > +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> > +
> > +	if (lane_num < 0 || lane_num > 3)
> 
> lane_num < 0 would not happen. lane_num > 3 only if device tree max
> lane is wrong. So I would like to checkout max lane when parsing
> device
> tree instead of checking here.
> > +		return false;
> > +
> > +	dev_dbg(mtk_dp->dev,
> > +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> > +		swing_val, preemphasis);
> > +
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> > + lane_shift),
> > +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> > +	if (ret)
> > +		return ret;
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> > + lane_shift),
> > +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> > +
> > +	return !ret;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:54       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 16:45 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp,
> > int
> > lane_num,
> > +					  int swing_val, int
> > preemphasis)
> 
> The return value is never processed, so let this function to be void.
> 
> Regards,
> CK
> 

Hello CK,

ok, I will drop this.
Actually, I change "mtk_dp_write", "mtk_dp_update_bits" and
"mtk_dp_bulk_16bit_write" to return void. I don't think we need to
handle the issue that we failed to set registers. If we failed to set
register, it's because hw is not enable.

Therefore, I drop this and we can reduce many lines of codes.

BRs,
Bo-Chen
> > +{
> > +	int ret;
> > +
> > +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> > +
> > +	if (lane_num < 0 || lane_num > 3)
> 
> lane_num < 0 would not happen. lane_num > 3 only if device tree max
> lane is wrong. So I would like to checkout max lane when parsing
> device
> tree instead of checking here.
> > +		return false;
> > +
> > +	dev_dbg(mtk_dp->dev,
> > +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> > +		swing_val, preemphasis);
> > +
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> > + lane_shift),
> > +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> > +	if (ret)
> > +		return ret;
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> > + lane_shift),
> > +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> > +
> > +	return !ret;
> > +}
> > +
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:54       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 16:45 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp,
> > int
> > lane_num,
> > +					  int swing_val, int
> > preemphasis)
> 
> The return value is never processed, so let this function to be void.
> 
> Regards,
> CK
> 

Hello CK,

ok, I will drop this.
Actually, I change "mtk_dp_write", "mtk_dp_update_bits" and
"mtk_dp_bulk_16bit_write" to return void. I don't think we need to
handle the issue that we failed to set registers. If we failed to set
register, it's because hw is not enable.

Therefore, I drop this and we can reduce many lines of codes.

BRs,
Bo-Chen
> > +{
> > +	int ret;
> > +
> > +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> > +
> > +	if (lane_num < 0 || lane_num > 3)
> 
> lane_num < 0 would not happen. lane_num > 3 only if device tree max
> lane is wrong. So I would like to checkout max lane when parsing
> device
> tree instead of checking here.
> > +		return false;
> > +
> > +	dev_dbg(mtk_dp->dev,
> > +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> > +		swing_val, preemphasis);
> > +
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> > + lane_shift),
> > +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> > +	if (ret)
> > +		return ret;
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> > + lane_shift),
> > +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> > +
> > +	return !ret;
> > +}
> > +
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:54       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 16:45 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp,
> > int
> > lane_num,
> > +					  int swing_val, int
> > preemphasis)
> 
> The return value is never processed, so let this function to be void.
> 
> Regards,
> CK
> 

Hello CK,

ok, I will drop this.
Actually, I change "mtk_dp_write", "mtk_dp_update_bits" and
"mtk_dp_bulk_16bit_write" to return void. I don't think we need to
handle the issue that we failed to set registers. If we failed to set
register, it's because hw is not enable.

Therefore, I drop this and we can reduce many lines of codes.

BRs,
Bo-Chen
> > +{
> > +	int ret;
> > +
> > +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> > +
> > +	if (lane_num < 0 || lane_num > 3)
> 
> lane_num < 0 would not happen. lane_num > 3 only if device tree max
> lane is wrong. So I would like to checkout max lane when parsing
> device
> tree instead of checking here.
> > +		return false;
> > +
> > +	dev_dbg(mtk_dp->dev,
> > +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> > +		swing_val, preemphasis);
> > +
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> > + lane_shift),
> > +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> > +	if (ret)
> > +		return ret;
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> > + lane_shift),
> > +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> > +
> > +	return !ret;
> > +}
> > +
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  8:54       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08  8:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 16:45 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp,
> > int
> > lane_num,
> > +					  int swing_val, int
> > preemphasis)
> 
> The return value is never processed, so let this function to be void.
> 
> Regards,
> CK
> 

Hello CK,

ok, I will drop this.
Actually, I change "mtk_dp_write", "mtk_dp_update_bits" and
"mtk_dp_bulk_16bit_write" to return void. I don't think we need to
handle the issue that we failed to set registers. If we failed to set
register, it's because hw is not enable.

Therefore, I drop this and we can reduce many lines of codes.

BRs,
Bo-Chen
> > +{
> > +	int ret;
> > +
> > +	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
> > +
> > +	if (lane_num < 0 || lane_num > 3)
> 
> lane_num < 0 would not happen. lane_num > 3 only if device tree max
> lane is wrong. So I would like to checkout max lane when parsing
> device
> tree instead of checking here.
> > +		return false;
> > +
> > +	dev_dbg(mtk_dp->dev,
> > +		"link training swing_val= 0x%x, preemphasis = 0x%x\n",
> > +		swing_val, preemphasis);
> > +
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 swing_val << (DP_TX0_VOLT_SWING_SHIFT
> > + lane_shift),
> > +				 DP_TX0_VOLT_SWING_MASK << lane_shift);
> > +	if (ret)
> > +		return ret;
> > +	ret = mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
> > +				 preemphasis << (DP_TX0_PRE_EMPH_SHIFT
> > + lane_shift),
> > +				 DP_TX0_PRE_EMPH_MASK << lane_shift);
> > +
> > +	return !ret;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-08  8:43           ` Rex-BC Chen
                               ` (2 preceding siblings ...)
  (?)
@ 2022-06-08  9:15             ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  9:15 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > Hi, Rex:
> > > > 
> > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > 
> > > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > > SoC.
> > > > > 
> > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > offers
> > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > 
> > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > ---
> > > > 
> > > > [snip]
> > > > 
> > > > > +
> > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > *dev)
> > > > > +{
> > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > +	int event;
> > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > +
> > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > connector_status_connected
> > > > > :
> > > > > +						  connector_sta
> > > > > tus_disc
> > > > > onnected;
> > > > > +
> > > > > +	if (event < 0)
> > > > 
> > > > event is always > 0, isn't it?
> > > > 
> > > 
> > > Hello CK,
> > > 
> > > ok, I will move this to dp patch.
> > > 
> > > > > +		return IRQ_HANDLED;
> > > > > +
> > > > > +	if (mtk_dp->drm_dev) {
> > > > > +		dev_info(mtk_dp->dev,
> > > > > "drm_helper_hpd_irq_event\n");
> > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > 
> > > > I think this ISR would come once. If bridge has not attached,
> > > > the
> > > > drm
> > > > core would lost this event. Maybe you should enable eDP
> > > > hardware
> > > > after
> > > > bridge attached or send this event when attached.
> > > > 
> > > 
> > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > for dp patch, I will add it back.
> > 
> > I find out that mtk_dp_poweron() is in top of
> > mtk_dp_bridge_attach().
> > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > mtk_dp-
> > > drm_dev would not be NULL here. So we could drop this checking.
> > > 
> 
> Hello CK,
> 
> If we failed to setup phy(ret!=0), we alos need to deattach this
> bridge.
> I don't think  it's a good idea just for remove this.

OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
bottom of mtk_dp_bridge_attach(). irq is not part of power.

> 
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > 
> > > > Executing this thread imply cable_state_change = true, so drop
> > > > cable_state_change.
> > > > 
> > > 
> > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > interrupt
> > > to
> > > source device. it's not about connected status, so I think we
> > > still
> > > need this.
> > 
> > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > 
> > +	train_info->cable_state_change = true;
> > +
> > +	return IRQ_WAKE_THREAD;
> > 
> > This thread is called only when return IRQ_WAKE_THREAD, and before
> > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > set
> > to
> > true. So in this thread, train_info->cable_state_change must be
> > true.
> > 
> 
> As mentioned, this irq handler function is not only for connected
> status.
> 
> this could be return if this irq is interrupt from sink device.
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;

According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
IRQ_HANDLED would not wake up thread.

[1] 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html

Regards,
CK

> 
> BRs,
> Bo-Chen
> > Regards,
> > CK
> > 
> > > 
> > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > +
> > > > > +		mtk_dp->train_state =
> > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > +
> > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > 
> > > > I do not like two variable to present one thing. If
> > > > 
> > > > mtk_dp->train_info.cable_plugged_in = false
> > > > and
> > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > 
> > > > What does this mean? I think this mean 'now' is connected
> > > > because
> > > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > > current
> > > > information.
> > > > 
> > > > But I would like to keep cable_plugged_in and drop
> > > > mtk_dp_plug_state()
> > > > because cable_plugged_in would be changed in isr and it would
> > > > be
> > > > the
> > > > same as mtk_dp_plug_state().
> > > > 
> > > > Regards,
> > > > CK
> > > > 
> > > 
> > > ok, I will drop this.
> > > 
> > > BRs,
> > > Rex
> > > 
> > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > +
> > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > +			if (mtk_dp->has_fec)
> > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > false);
> > > > > +
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +		} else {
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL_LA
> > > > > NE,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > buf);
> > > > > +			mtk_dp->train_info.link_rate =
> > > > > +				min_t(int, mtk_dp-
> > > > > > max_linkrate,
> > > > > 
> > > > > +				      buf[mtk_dp-
> > > > > > max_linkrate]);
> > > > > 
> > > > > +			mtk_dp->train_info.lane_count =
> > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > +				      drm_dp_max_lane_count(buf
> > > > > ));
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > +		mtk_dp->train_info.irq_status &=
> > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > +	}
> > > > > +
> > > > > +	return IRQ_HANDLED;
> > > > > +}
> > > > > +
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  9:15             ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  9:15 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > Hi, Rex:
> > > > 
> > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > 
> > > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > > SoC.
> > > > > 
> > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > offers
> > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > 
> > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > ---
> > > > 
> > > > [snip]
> > > > 
> > > > > +
> > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > *dev)
> > > > > +{
> > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > +	int event;
> > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > +
> > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > connector_status_connected
> > > > > :
> > > > > +						  connector_sta
> > > > > tus_disc
> > > > > onnected;
> > > > > +
> > > > > +	if (event < 0)
> > > > 
> > > > event is always > 0, isn't it?
> > > > 
> > > 
> > > Hello CK,
> > > 
> > > ok, I will move this to dp patch.
> > > 
> > > > > +		return IRQ_HANDLED;
> > > > > +
> > > > > +	if (mtk_dp->drm_dev) {
> > > > > +		dev_info(mtk_dp->dev,
> > > > > "drm_helper_hpd_irq_event\n");
> > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > 
> > > > I think this ISR would come once. If bridge has not attached,
> > > > the
> > > > drm
> > > > core would lost this event. Maybe you should enable eDP
> > > > hardware
> > > > after
> > > > bridge attached or send this event when attached.
> > > > 
> > > 
> > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > for dp patch, I will add it back.
> > 
> > I find out that mtk_dp_poweron() is in top of
> > mtk_dp_bridge_attach().
> > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > mtk_dp-
> > > drm_dev would not be NULL here. So we could drop this checking.
> > > 
> 
> Hello CK,
> 
> If we failed to setup phy(ret!=0), we alos need to deattach this
> bridge.
> I don't think  it's a good idea just for remove this.

OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
bottom of mtk_dp_bridge_attach(). irq is not part of power.

> 
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > 
> > > > Executing this thread imply cable_state_change = true, so drop
> > > > cable_state_change.
> > > > 
> > > 
> > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > interrupt
> > > to
> > > source device. it's not about connected status, so I think we
> > > still
> > > need this.
> > 
> > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > 
> > +	train_info->cable_state_change = true;
> > +
> > +	return IRQ_WAKE_THREAD;
> > 
> > This thread is called only when return IRQ_WAKE_THREAD, and before
> > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > set
> > to
> > true. So in this thread, train_info->cable_state_change must be
> > true.
> > 
> 
> As mentioned, this irq handler function is not only for connected
> status.
> 
> this could be return if this irq is interrupt from sink device.
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;

According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
IRQ_HANDLED would not wake up thread.

[1] 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html

Regards,
CK

> 
> BRs,
> Bo-Chen
> > Regards,
> > CK
> > 
> > > 
> > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > +
> > > > > +		mtk_dp->train_state =
> > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > +
> > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > 
> > > > I do not like two variable to present one thing. If
> > > > 
> > > > mtk_dp->train_info.cable_plugged_in = false
> > > > and
> > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > 
> > > > What does this mean? I think this mean 'now' is connected
> > > > because
> > > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > > current
> > > > information.
> > > > 
> > > > But I would like to keep cable_plugged_in and drop
> > > > mtk_dp_plug_state()
> > > > because cable_plugged_in would be changed in isr and it would
> > > > be
> > > > the
> > > > same as mtk_dp_plug_state().
> > > > 
> > > > Regards,
> > > > CK
> > > > 
> > > 
> > > ok, I will drop this.
> > > 
> > > BRs,
> > > Rex
> > > 
> > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > +
> > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > +			if (mtk_dp->has_fec)
> > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > false);
> > > > > +
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +		} else {
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL_LA
> > > > > NE,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > buf);
> > > > > +			mtk_dp->train_info.link_rate =
> > > > > +				min_t(int, mtk_dp-
> > > > > > max_linkrate,
> > > > > 
> > > > > +				      buf[mtk_dp-
> > > > > > max_linkrate]);
> > > > > 
> > > > > +			mtk_dp->train_info.lane_count =
> > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > +				      drm_dp_max_lane_count(buf
> > > > > ));
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > +		mtk_dp->train_info.irq_status &=
> > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > +	}
> > > > > +
> > > > > +	return IRQ_HANDLED;
> > > > > +}
> > > > > +
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  9:15             ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  9:15 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > Hi, Rex:
> > > > 
> > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > 
> > > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > > SoC.
> > > > > 
> > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > offers
> > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > 
> > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > ---
> > > > 
> > > > [snip]
> > > > 
> > > > > +
> > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > *dev)
> > > > > +{
> > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > +	int event;
> > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > +
> > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > connector_status_connected
> > > > > :
> > > > > +						  connector_sta
> > > > > tus_disc
> > > > > onnected;
> > > > > +
> > > > > +	if (event < 0)
> > > > 
> > > > event is always > 0, isn't it?
> > > > 
> > > 
> > > Hello CK,
> > > 
> > > ok, I will move this to dp patch.
> > > 
> > > > > +		return IRQ_HANDLED;
> > > > > +
> > > > > +	if (mtk_dp->drm_dev) {
> > > > > +		dev_info(mtk_dp->dev,
> > > > > "drm_helper_hpd_irq_event\n");
> > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > 
> > > > I think this ISR would come once. If bridge has not attached,
> > > > the
> > > > drm
> > > > core would lost this event. Maybe you should enable eDP
> > > > hardware
> > > > after
> > > > bridge attached or send this event when attached.
> > > > 
> > > 
> > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > for dp patch, I will add it back.
> > 
> > I find out that mtk_dp_poweron() is in top of
> > mtk_dp_bridge_attach().
> > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > mtk_dp-
> > > drm_dev would not be NULL here. So we could drop this checking.
> > > 
> 
> Hello CK,
> 
> If we failed to setup phy(ret!=0), we alos need to deattach this
> bridge.
> I don't think  it's a good idea just for remove this.

OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
bottom of mtk_dp_bridge_attach(). irq is not part of power.

> 
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > 
> > > > Executing this thread imply cable_state_change = true, so drop
> > > > cable_state_change.
> > > > 
> > > 
> > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > interrupt
> > > to
> > > source device. it's not about connected status, so I think we
> > > still
> > > need this.
> > 
> > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > 
> > +	train_info->cable_state_change = true;
> > +
> > +	return IRQ_WAKE_THREAD;
> > 
> > This thread is called only when return IRQ_WAKE_THREAD, and before
> > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > set
> > to
> > true. So in this thread, train_info->cable_state_change must be
> > true.
> > 
> 
> As mentioned, this irq handler function is not only for connected
> status.
> 
> this could be return if this irq is interrupt from sink device.
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;

According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
IRQ_HANDLED would not wake up thread.

[1] 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html

Regards,
CK

> 
> BRs,
> Bo-Chen
> > Regards,
> > CK
> > 
> > > 
> > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > +
> > > > > +		mtk_dp->train_state =
> > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > +
> > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > 
> > > > I do not like two variable to present one thing. If
> > > > 
> > > > mtk_dp->train_info.cable_plugged_in = false
> > > > and
> > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > 
> > > > What does this mean? I think this mean 'now' is connected
> > > > because
> > > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > > current
> > > > information.
> > > > 
> > > > But I would like to keep cable_plugged_in and drop
> > > > mtk_dp_plug_state()
> > > > because cable_plugged_in would be changed in isr and it would
> > > > be
> > > > the
> > > > same as mtk_dp_plug_state().
> > > > 
> > > > Regards,
> > > > CK
> > > > 
> > > 
> > > ok, I will drop this.
> > > 
> > > BRs,
> > > Rex
> > > 
> > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > +
> > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > +			if (mtk_dp->has_fec)
> > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > false);
> > > > > +
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +		} else {
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL_LA
> > > > > NE,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > buf);
> > > > > +			mtk_dp->train_info.link_rate =
> > > > > +				min_t(int, mtk_dp-
> > > > > > max_linkrate,
> > > > > 
> > > > > +				      buf[mtk_dp-
> > > > > > max_linkrate]);
> > > > > 
> > > > > +			mtk_dp->train_info.lane_count =
> > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > +				      drm_dp_max_lane_count(buf
> > > > > ));
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > +		mtk_dp->train_info.irq_status &=
> > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > +	}
> > > > > +
> > > > > +	return IRQ_HANDLED;
> > > > > +}
> > > > > +
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  9:15             ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  9:15 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > Hi, Rex:
> > > > 
> > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > 
> > > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > > SoC.
> > > > > 
> > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > offers
> > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > 
> > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > ---
> > > > 
> > > > [snip]
> > > > 
> > > > > +
> > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > *dev)
> > > > > +{
> > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > +	int event;
> > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > +
> > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > connector_status_connected
> > > > > :
> > > > > +						  connector_sta
> > > > > tus_disc
> > > > > onnected;
> > > > > +
> > > > > +	if (event < 0)
> > > > 
> > > > event is always > 0, isn't it?
> > > > 
> > > 
> > > Hello CK,
> > > 
> > > ok, I will move this to dp patch.
> > > 
> > > > > +		return IRQ_HANDLED;
> > > > > +
> > > > > +	if (mtk_dp->drm_dev) {
> > > > > +		dev_info(mtk_dp->dev,
> > > > > "drm_helper_hpd_irq_event\n");
> > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > 
> > > > I think this ISR would come once. If bridge has not attached,
> > > > the
> > > > drm
> > > > core would lost this event. Maybe you should enable eDP
> > > > hardware
> > > > after
> > > > bridge attached or send this event when attached.
> > > > 
> > > 
> > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > for dp patch, I will add it back.
> > 
> > I find out that mtk_dp_poweron() is in top of
> > mtk_dp_bridge_attach().
> > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > mtk_dp-
> > > drm_dev would not be NULL here. So we could drop this checking.
> > > 
> 
> Hello CK,
> 
> If we failed to setup phy(ret!=0), we alos need to deattach this
> bridge.
> I don't think  it's a good idea just for remove this.

OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
bottom of mtk_dp_bridge_attach(). irq is not part of power.

> 
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > 
> > > > Executing this thread imply cable_state_change = true, so drop
> > > > cable_state_change.
> > > > 
> > > 
> > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > interrupt
> > > to
> > > source device. it's not about connected status, so I think we
> > > still
> > > need this.
> > 
> > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > 
> > +	train_info->cable_state_change = true;
> > +
> > +	return IRQ_WAKE_THREAD;
> > 
> > This thread is called only when return IRQ_WAKE_THREAD, and before
> > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > set
> > to
> > true. So in this thread, train_info->cable_state_change must be
> > true.
> > 
> 
> As mentioned, this irq handler function is not only for connected
> status.
> 
> this could be return if this irq is interrupt from sink device.
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;

According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
IRQ_HANDLED would not wake up thread.

[1] 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html

Regards,
CK

> 
> BRs,
> Bo-Chen
> > Regards,
> > CK
> > 
> > > 
> > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > +
> > > > > +		mtk_dp->train_state =
> > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > +
> > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > 
> > > > I do not like two variable to present one thing. If
> > > > 
> > > > mtk_dp->train_info.cable_plugged_in = false
> > > > and
> > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > 
> > > > What does this mean? I think this mean 'now' is connected
> > > > because
> > > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > > current
> > > > information.
> > > > 
> > > > But I would like to keep cable_plugged_in and drop
> > > > mtk_dp_plug_state()
> > > > because cable_plugged_in would be changed in isr and it would
> > > > be
> > > > the
> > > > same as mtk_dp_plug_state().
> > > > 
> > > > Regards,
> > > > CK
> > > > 
> > > 
> > > ok, I will drop this.
> > > 
> > > BRs,
> > > Rex
> > > 
> > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > +
> > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > +			if (mtk_dp->has_fec)
> > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > false);
> > > > > +
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +		} else {
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL_LA
> > > > > NE,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > buf);
> > > > > +			mtk_dp->train_info.link_rate =
> > > > > +				min_t(int, mtk_dp-
> > > > > > max_linkrate,
> > > > > 
> > > > > +				      buf[mtk_dp-
> > > > > > max_linkrate]);
> > > > > 
> > > > > +			mtk_dp->train_info.lane_count =
> > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > +				      drm_dp_max_lane_count(buf
> > > > > ));
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > +		mtk_dp->train_info.irq_status &=
> > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > +	}
> > > > > +
> > > > > +	return IRQ_HANDLED;
> > > > > +}
> > > > > +
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08  9:15             ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-08  9:15 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > Hi, Rex:
> > > > 
> > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > 
> > > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > > SoC.
> > > > > 
> > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > offers
> > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > 
> > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > ---
> > > > 
> > > > [snip]
> > > > 
> > > > > +
> > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > *dev)
> > > > > +{
> > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > +	int event;
> > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > +
> > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > connector_status_connected
> > > > > :
> > > > > +						  connector_sta
> > > > > tus_disc
> > > > > onnected;
> > > > > +
> > > > > +	if (event < 0)
> > > > 
> > > > event is always > 0, isn't it?
> > > > 
> > > 
> > > Hello CK,
> > > 
> > > ok, I will move this to dp patch.
> > > 
> > > > > +		return IRQ_HANDLED;
> > > > > +
> > > > > +	if (mtk_dp->drm_dev) {
> > > > > +		dev_info(mtk_dp->dev,
> > > > > "drm_helper_hpd_irq_event\n");
> > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > 
> > > > I think this ISR would come once. If bridge has not attached,
> > > > the
> > > > drm
> > > > core would lost this event. Maybe you should enable eDP
> > > > hardware
> > > > after
> > > > bridge attached or send this event when attached.
> > > > 
> > > 
> > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > for dp patch, I will add it back.
> > 
> > I find out that mtk_dp_poweron() is in top of
> > mtk_dp_bridge_attach().
> > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > mtk_dp-
> > > drm_dev would not be NULL here. So we could drop this checking.
> > > 
> 
> Hello CK,
> 
> If we failed to setup phy(ret!=0), we alos need to deattach this
> bridge.
> I don't think  it's a good idea just for remove this.

OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
bottom of mtk_dp_bridge_attach(). irq is not part of power.

> 
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > 
> > > > Executing this thread imply cable_state_change = true, so drop
> > > > cable_state_change.
> > > > 
> > > 
> > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > interrupt
> > > to
> > > source device. it's not about connected status, so I think we
> > > still
> > > need this.
> > 
> > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > 
> > +	train_info->cable_state_change = true;
> > +
> > +	return IRQ_WAKE_THREAD;
> > 
> > This thread is called only when return IRQ_WAKE_THREAD, and before
> > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > set
> > to
> > true. So in this thread, train_info->cable_state_change must be
> > true.
> > 
> 
> As mentioned, this irq handler function is not only for connected
> status.
> 
> this could be return if this irq is interrupt from sink device.
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;

According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
IRQ_HANDLED would not wake up thread.

[1] 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html

Regards,
CK

> 
> BRs,
> Bo-Chen
> > Regards,
> > CK
> > 
> > > 
> > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > +
> > > > > +		mtk_dp->train_state =
> > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > +
> > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > 
> > > > I do not like two variable to present one thing. If
> > > > 
> > > > mtk_dp->train_info.cable_plugged_in = false
> > > > and
> > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > 
> > > > What does this mean? I think this mean 'now' is connected
> > > > because
> > > > cable_plugged_in is old information and mtk_dp_plug_state() is
> > > > current
> > > > information.
> > > > 
> > > > But I would like to keep cable_plugged_in and drop
> > > > mtk_dp_plug_state()
> > > > because cable_plugged_in would be changed in isr and it would
> > > > be
> > > > the
> > > > same as mtk_dp_plug_state().
> > > > 
> > > > Regards,
> > > > CK
> > > > 
> > > 
> > > ok, I will drop this.
> > > 
> > > BRs,
> > > Rex
> > > 
> > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > +
> > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > +			if (mtk_dp->has_fec)
> > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > false);
> > > > > +
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +		} else {
> > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > MTK_DP_TOP_PWR_STATE,
> > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > _TPLL_LA
> > > > > NE,
> > > > > +					   DP_PWR_STATE_MASK);
> > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > buf);
> > > > > +			mtk_dp->train_info.link_rate =
> > > > > +				min_t(int, mtk_dp-
> > > > > > max_linkrate,
> > > > > 
> > > > > +				      buf[mtk_dp-
> > > > > > max_linkrate]);
> > > > > 
> > > > > +			mtk_dp->train_info.lane_count =
> > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > +				      drm_dp_max_lane_count(buf
> > > > > ));
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > +		mtk_dp->train_info.irq_status &=
> > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > +	}
> > > > > +
> > > > > +	return IRQ_HANDLED;
> > > > > +}
> > > > > +
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07  7:47     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-08 10:26       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 10:26 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > +{
> > +	ssize_t ret;
> > +	u8 sink_count;
> > +	bool locked;
> > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > +
> > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > &sink_count);
> > +	if (ret < 0) {
> > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > %ld\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > link_status,
> > +			       sizeof(link_status));
> > +	if (!ret) {
> > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > %ld\n",
> > +			ret);
> > +		return ret;
> > +	}
> > +
> > +	locked = drm_dp_channel_eq_ok(link_status,
> > +				      mtk_dp->train_info.lane_count);
> > +	if (!locked && mtk_dp->train_state >
> > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> 
> Before enter this function, mtk_dp->train_state is set to
> MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> 

The interrupt from sink device could come any time. Why it's
impossible?

> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > +
> > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > +
> > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > +		mtk_dp->train_info.check_cap_count = 0;
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> 
> Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> mtk_dp_parse_capabilities() is true then change to
> MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> different.
> 
> Regards,
> CK
> 

I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
We can check enable status in another place.

BRs,
Bo-Chen

> > +		msleep(20);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 10:26       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 10:26 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > +{
> > +	ssize_t ret;
> > +	u8 sink_count;
> > +	bool locked;
> > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > +
> > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > &sink_count);
> > +	if (ret < 0) {
> > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > %ld\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > link_status,
> > +			       sizeof(link_status));
> > +	if (!ret) {
> > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > %ld\n",
> > +			ret);
> > +		return ret;
> > +	}
> > +
> > +	locked = drm_dp_channel_eq_ok(link_status,
> > +				      mtk_dp->train_info.lane_count);
> > +	if (!locked && mtk_dp->train_state >
> > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> 
> Before enter this function, mtk_dp->train_state is set to
> MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> 

The interrupt from sink device could come any time. Why it's
impossible?

> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > +
> > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > +
> > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > +		mtk_dp->train_info.check_cap_count = 0;
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> 
> Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> mtk_dp_parse_capabilities() is true then change to
> MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> different.
> 
> Regards,
> CK
> 

I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
We can check enable status in another place.

BRs,
Bo-Chen

> > +		msleep(20);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 10:26       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 10:26 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > +{
> > +	ssize_t ret;
> > +	u8 sink_count;
> > +	bool locked;
> > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > +
> > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > &sink_count);
> > +	if (ret < 0) {
> > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > %ld\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > link_status,
> > +			       sizeof(link_status));
> > +	if (!ret) {
> > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > %ld\n",
> > +			ret);
> > +		return ret;
> > +	}
> > +
> > +	locked = drm_dp_channel_eq_ok(link_status,
> > +				      mtk_dp->train_info.lane_count);
> > +	if (!locked && mtk_dp->train_state >
> > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> 
> Before enter this function, mtk_dp->train_state is set to
> MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> 

The interrupt from sink device could come any time. Why it's
impossible?

> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > +
> > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > +
> > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > +		mtk_dp->train_info.check_cap_count = 0;
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> 
> Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> mtk_dp_parse_capabilities() is true then change to
> MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> different.
> 
> Regards,
> CK
> 

I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
We can check enable status in another place.

BRs,
Bo-Chen

> > +		msleep(20);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 10:26       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 10:26 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > +{
> > +	ssize_t ret;
> > +	u8 sink_count;
> > +	bool locked;
> > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > +
> > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > &sink_count);
> > +	if (ret < 0) {
> > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > %ld\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > link_status,
> > +			       sizeof(link_status));
> > +	if (!ret) {
> > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > %ld\n",
> > +			ret);
> > +		return ret;
> > +	}
> > +
> > +	locked = drm_dp_channel_eq_ok(link_status,
> > +				      mtk_dp->train_info.lane_count);
> > +	if (!locked && mtk_dp->train_state >
> > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> 
> Before enter this function, mtk_dp->train_state is set to
> MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> 

The interrupt from sink device could come any time. Why it's
impossible?

> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > +
> > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > +
> > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > +		mtk_dp->train_info.check_cap_count = 0;
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> 
> Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> mtk_dp_parse_capabilities() is true then change to
> MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> different.
> 
> Regards,
> CK
> 

I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
We can check enable status in another place.

BRs,
Bo-Chen

> > +		msleep(20);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 10:26       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 10:26 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > +{
> > +	ssize_t ret;
> > +	u8 sink_count;
> > +	bool locked;
> > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > +
> > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > &sink_count);
> > +	if (ret < 0) {
> > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > %ld\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > link_status,
> > +			       sizeof(link_status));
> > +	if (!ret) {
> > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > %ld\n",
> > +			ret);
> > +		return ret;
> > +	}
> > +
> > +	locked = drm_dp_channel_eq_ok(link_status,
> > +				      mtk_dp->train_info.lane_count);
> > +	if (!locked && mtk_dp->train_state >
> > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> 
> Before enter this function, mtk_dp->train_state is set to
> MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> 

The interrupt from sink device could come any time. Why it's
impossible?

> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > +
> > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > +
> > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > +		mtk_dp->train_info.check_cap_count = 0;
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> 
> Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> mtk_dp_parse_capabilities() is true then change to
> MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> different.
> 
> Regards,
> CK
> 

I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
We can check enable status in another place.

BRs,
Bo-Chen

> > +		msleep(20);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-08  9:15             ` CK Hu
                                 ` (2 preceding siblings ...)
  (?)
@ 2022-06-08 11:52               ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 11:52 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 17:15 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> > On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > > Hi, Rex:
> > > > > 
> > > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > 
> > > > > > This patch adds a DisplayPort driver for the Mediatek
> > > > > > mt8195
> > > > > > SoC.
> > > > > > 
> > > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > > offers
> > > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > > 
> > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > > ---
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > > +
> > > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > > *dev)
> > > > > > +{
> > > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > > +	int event;
> > > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > > +
> > > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > > connector_status_connected
> > > > > > :
> > > > > > +						  connector_sta
> > > > > > tus_disc
> > > > > > onnected;
> > > > > > +
> > > > > > +	if (event < 0)
> > > > > 
> > > > > event is always > 0, isn't it?
> > > > > 
> > > > 
> > > > Hello CK,
> > > > 
> > > > ok, I will move this to dp patch.
> > > > 
> > > > > > +		return IRQ_HANDLED;
> > > > > > +
> > > > > > +	if (mtk_dp->drm_dev) {
> > > > > > +		dev_info(mtk_dp->dev,
> > > > > > "drm_helper_hpd_irq_event\n");
> > > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > > 
> > > > > I think this ISR would come once. If bridge has not attached,
> > > > > the
> > > > > drm
> > > > > core would lost this event. Maybe you should enable eDP
> > > > > hardware
> > > > > after
> > > > > bridge attached or send this event when attached.
> > > > > 
> > > > 
> > > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > > for dp patch, I will add it back.
> > > 
> > > I find out that mtk_dp_poweron() is in top of
> > > mtk_dp_bridge_attach().
> > > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > > mtk_dp-
> > > > drm_dev would not be NULL here. So we could drop this checking.
> > > > 
> > 
> > Hello CK,
> > 
> > If we failed to setup phy(ret!=0), we alos need to deattach this
> > bridge.
> > I don't think  it's a good idea just for remove this.
> 
> OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
> bottom of mtk_dp_bridge_attach(). irq is not part of power.
> 

I will do this and drop "if (mtk_dp->drm_dev)"

> > 
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > > 
> > > > > Executing this thread imply cable_state_change = true, so
> > > > > drop
> > > > > cable_state_change.
> > > > > 
> > > > 
> > > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > > interrupt
> > > > to
> > > > source device. it's not about connected status, so I think we
> > > > still
> > > > need this.
> > > 
> > > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > > 
> > > +	train_info->cable_state_change = true;
> > > +
> > > +	return IRQ_WAKE_THREAD;
> > > 
> > > This thread is called only when return IRQ_WAKE_THREAD, and
> > > before
> > > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > > set
> > > to
> > > true. So in this thread, train_info->cable_state_change must be
> > > true.
> > > 
> > 
> > As mentioned, this irq handler function is not only for connected
> > status.
> > 
> > this could be return if this irq is interrupt from sink device.
> > +	if (!(train_info->irq_status &
> > +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> > +		return IRQ_HANDLED;
> 
> According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
> IRQ_HANDLED would not wake up thread.
> 
> [1] 
> 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html
> 
> Regards,
> CK
> 

yes, you are right. I will return IRQ_WAKE_THREAD for handle sink
interrupt.

> > 
> > BRs,
> > Bo-Chen
> > > Regards,
> > > CK
> > > 
> > > > 
> > > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > > +
> > > > > > +		mtk_dp->train_state =
> > > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > > +
> > > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > > 
> > > > > I do not like two variable to present one thing. If
> > > > > 
> > > > > mtk_dp->train_info.cable_plugged_in = false
> > > > > and
> > > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > > 
> > > > > What does this mean? I think this mean 'now' is connected
> > > > > because
> > > > > cable_plugged_in is old information and mtk_dp_plug_state()
> > > > > is
> > > > > current
> > > > > information.
> > > > > 
> > > > > But I would like to keep cable_plugged_in and drop
> > > > > mtk_dp_plug_state()
> > > > > because cable_plugged_in would be changed in isr and it would
> > > > > be
> > > > > the
> > > > > same as mtk_dp_plug_state().
> > > > > 
> > > > > Regards,
> > > > > CK
> > > > > 
> > > > 
> > > > ok, I will drop this.
> > > > 
> > > > BRs,
> > > > Rex
> > > > 
> > > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > > +
> > > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > > +			if (mtk_dp->has_fec)
> > > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > > false);
> > > > > > +
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +		} else {
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL_LA
> > > > > > NE,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > > buf);
> > > > > > +			mtk_dp->train_info.link_rate =
> > > > > > +				min_t(int, mtk_dp-
> > > > > > > max_linkrate,
> > > > > > 
> > > > > > +				      buf[mtk_dp-
> > > > > > > max_linkrate]);
> > > > > > 
> > > > > > +			mtk_dp->train_info.lane_count =
> > > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > > +				      drm_dp_max_lane_count(buf
> > > > > > ));
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > > +		mtk_dp->train_info.irq_status &=
> > > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > > +	}
> > > > > > +
> > > > > > +	return IRQ_HANDLED;
> > > > > > +}
> > > > > > +
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 11:52               ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 11:52 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 17:15 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> > On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > > Hi, Rex:
> > > > > 
> > > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > 
> > > > > > This patch adds a DisplayPort driver for the Mediatek
> > > > > > mt8195
> > > > > > SoC.
> > > > > > 
> > > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > > offers
> > > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > > 
> > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > > ---
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > > +
> > > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > > *dev)
> > > > > > +{
> > > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > > +	int event;
> > > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > > +
> > > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > > connector_status_connected
> > > > > > :
> > > > > > +						  connector_sta
> > > > > > tus_disc
> > > > > > onnected;
> > > > > > +
> > > > > > +	if (event < 0)
> > > > > 
> > > > > event is always > 0, isn't it?
> > > > > 
> > > > 
> > > > Hello CK,
> > > > 
> > > > ok, I will move this to dp patch.
> > > > 
> > > > > > +		return IRQ_HANDLED;
> > > > > > +
> > > > > > +	if (mtk_dp->drm_dev) {
> > > > > > +		dev_info(mtk_dp->dev,
> > > > > > "drm_helper_hpd_irq_event\n");
> > > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > > 
> > > > > I think this ISR would come once. If bridge has not attached,
> > > > > the
> > > > > drm
> > > > > core would lost this event. Maybe you should enable eDP
> > > > > hardware
> > > > > after
> > > > > bridge attached or send this event when attached.
> > > > > 
> > > > 
> > > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > > for dp patch, I will add it back.
> > > 
> > > I find out that mtk_dp_poweron() is in top of
> > > mtk_dp_bridge_attach().
> > > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > > mtk_dp-
> > > > drm_dev would not be NULL here. So we could drop this checking.
> > > > 
> > 
> > Hello CK,
> > 
> > If we failed to setup phy(ret!=0), we alos need to deattach this
> > bridge.
> > I don't think  it's a good idea just for remove this.
> 
> OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
> bottom of mtk_dp_bridge_attach(). irq is not part of power.
> 

I will do this and drop "if (mtk_dp->drm_dev)"

> > 
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > > 
> > > > > Executing this thread imply cable_state_change = true, so
> > > > > drop
> > > > > cable_state_change.
> > > > > 
> > > > 
> > > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > > interrupt
> > > > to
> > > > source device. it's not about connected status, so I think we
> > > > still
> > > > need this.
> > > 
> > > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > > 
> > > +	train_info->cable_state_change = true;
> > > +
> > > +	return IRQ_WAKE_THREAD;
> > > 
> > > This thread is called only when return IRQ_WAKE_THREAD, and
> > > before
> > > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > > set
> > > to
> > > true. So in this thread, train_info->cable_state_change must be
> > > true.
> > > 
> > 
> > As mentioned, this irq handler function is not only for connected
> > status.
> > 
> > this could be return if this irq is interrupt from sink device.
> > +	if (!(train_info->irq_status &
> > +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> > +		return IRQ_HANDLED;
> 
> According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
> IRQ_HANDLED would not wake up thread.
> 
> [1] 
> 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html
> 
> Regards,
> CK
> 

yes, you are right. I will return IRQ_WAKE_THREAD for handle sink
interrupt.

> > 
> > BRs,
> > Bo-Chen
> > > Regards,
> > > CK
> > > 
> > > > 
> > > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > > +
> > > > > > +		mtk_dp->train_state =
> > > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > > +
> > > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > > 
> > > > > I do not like two variable to present one thing. If
> > > > > 
> > > > > mtk_dp->train_info.cable_plugged_in = false
> > > > > and
> > > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > > 
> > > > > What does this mean? I think this mean 'now' is connected
> > > > > because
> > > > > cable_plugged_in is old information and mtk_dp_plug_state()
> > > > > is
> > > > > current
> > > > > information.
> > > > > 
> > > > > But I would like to keep cable_plugged_in and drop
> > > > > mtk_dp_plug_state()
> > > > > because cable_plugged_in would be changed in isr and it would
> > > > > be
> > > > > the
> > > > > same as mtk_dp_plug_state().
> > > > > 
> > > > > Regards,
> > > > > CK
> > > > > 
> > > > 
> > > > ok, I will drop this.
> > > > 
> > > > BRs,
> > > > Rex
> > > > 
> > > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > > +
> > > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > > +			if (mtk_dp->has_fec)
> > > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > > false);
> > > > > > +
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +		} else {
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL_LA
> > > > > > NE,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > > buf);
> > > > > > +			mtk_dp->train_info.link_rate =
> > > > > > +				min_t(int, mtk_dp-
> > > > > > > max_linkrate,
> > > > > > 
> > > > > > +				      buf[mtk_dp-
> > > > > > > max_linkrate]);
> > > > > > 
> > > > > > +			mtk_dp->train_info.lane_count =
> > > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > > +				      drm_dp_max_lane_count(buf
> > > > > > ));
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > > +		mtk_dp->train_info.irq_status &=
> > > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > > +	}
> > > > > > +
> > > > > > +	return IRQ_HANDLED;
> > > > > > +}
> > > > > > +
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 11:52               ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 11:52 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-06-08 at 17:15 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> > On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > > Hi, Rex:
> > > > > 
> > > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > 
> > > > > > This patch adds a DisplayPort driver for the Mediatek
> > > > > > mt8195
> > > > > > SoC.
> > > > > > 
> > > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > > offers
> > > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > > 
> > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > > ---
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > > +
> > > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > > *dev)
> > > > > > +{
> > > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > > +	int event;
> > > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > > +
> > > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > > connector_status_connected
> > > > > > :
> > > > > > +						  connector_sta
> > > > > > tus_disc
> > > > > > onnected;
> > > > > > +
> > > > > > +	if (event < 0)
> > > > > 
> > > > > event is always > 0, isn't it?
> > > > > 
> > > > 
> > > > Hello CK,
> > > > 
> > > > ok, I will move this to dp patch.
> > > > 
> > > > > > +		return IRQ_HANDLED;
> > > > > > +
> > > > > > +	if (mtk_dp->drm_dev) {
> > > > > > +		dev_info(mtk_dp->dev,
> > > > > > "drm_helper_hpd_irq_event\n");
> > > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > > 
> > > > > I think this ISR would come once. If bridge has not attached,
> > > > > the
> > > > > drm
> > > > > core would lost this event. Maybe you should enable eDP
> > > > > hardware
> > > > > after
> > > > > bridge attached or send this event when attached.
> > > > > 
> > > > 
> > > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > > for dp patch, I will add it back.
> > > 
> > > I find out that mtk_dp_poweron() is in top of
> > > mtk_dp_bridge_attach().
> > > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > > mtk_dp-
> > > > drm_dev would not be NULL here. So we could drop this checking.
> > > > 
> > 
> > Hello CK,
> > 
> > If we failed to setup phy(ret!=0), we alos need to deattach this
> > bridge.
> > I don't think  it's a good idea just for remove this.
> 
> OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
> bottom of mtk_dp_bridge_attach(). irq is not part of power.
> 

I will do this and drop "if (mtk_dp->drm_dev)"

> > 
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > > 
> > > > > Executing this thread imply cable_state_change = true, so
> > > > > drop
> > > > > cable_state_change.
> > > > > 
> > > > 
> > > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > > interrupt
> > > > to
> > > > source device. it's not about connected status, so I think we
> > > > still
> > > > need this.
> > > 
> > > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > > 
> > > +	train_info->cable_state_change = true;
> > > +
> > > +	return IRQ_WAKE_THREAD;
> > > 
> > > This thread is called only when return IRQ_WAKE_THREAD, and
> > > before
> > > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > > set
> > > to
> > > true. So in this thread, train_info->cable_state_change must be
> > > true.
> > > 
> > 
> > As mentioned, this irq handler function is not only for connected
> > status.
> > 
> > this could be return if this irq is interrupt from sink device.
> > +	if (!(train_info->irq_status &
> > +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> > +		return IRQ_HANDLED;
> 
> According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
> IRQ_HANDLED would not wake up thread.
> 
> [1] 
> 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html
> 
> Regards,
> CK
> 

yes, you are right. I will return IRQ_WAKE_THREAD for handle sink
interrupt.

> > 
> > BRs,
> > Bo-Chen
> > > Regards,
> > > CK
> > > 
> > > > 
> > > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > > +
> > > > > > +		mtk_dp->train_state =
> > > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > > +
> > > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > > 
> > > > > I do not like two variable to present one thing. If
> > > > > 
> > > > > mtk_dp->train_info.cable_plugged_in = false
> > > > > and
> > > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > > 
> > > > > What does this mean? I think this mean 'now' is connected
> > > > > because
> > > > > cable_plugged_in is old information and mtk_dp_plug_state()
> > > > > is
> > > > > current
> > > > > information.
> > > > > 
> > > > > But I would like to keep cable_plugged_in and drop
> > > > > mtk_dp_plug_state()
> > > > > because cable_plugged_in would be changed in isr and it would
> > > > > be
> > > > > the
> > > > > same as mtk_dp_plug_state().
> > > > > 
> > > > > Regards,
> > > > > CK
> > > > > 
> > > > 
> > > > ok, I will drop this.
> > > > 
> > > > BRs,
> > > > Rex
> > > > 
> > > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > > +
> > > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > > +			if (mtk_dp->has_fec)
> > > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > > false);
> > > > > > +
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +		} else {
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL_LA
> > > > > > NE,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > > buf);
> > > > > > +			mtk_dp->train_info.link_rate =
> > > > > > +				min_t(int, mtk_dp-
> > > > > > > max_linkrate,
> > > > > > 
> > > > > > +				      buf[mtk_dp-
> > > > > > > max_linkrate]);
> > > > > > 
> > > > > > +			mtk_dp->train_info.lane_count =
> > > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > > +				      drm_dp_max_lane_count(buf
> > > > > > ));
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > > +		mtk_dp->train_info.irq_status &=
> > > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > > +	}
> > > > > > +
> > > > > > +	return IRQ_HANDLED;
> > > > > > +}
> > > > > > +
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 11:52               ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 11:52 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 17:15 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> > On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > > Hi, Rex:
> > > > > 
> > > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > 
> > > > > > This patch adds a DisplayPort driver for the Mediatek
> > > > > > mt8195
> > > > > > SoC.
> > > > > > 
> > > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > > offers
> > > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > > 
> > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > > ---
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > > +
> > > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > > *dev)
> > > > > > +{
> > > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > > +	int event;
> > > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > > +
> > > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > > connector_status_connected
> > > > > > :
> > > > > > +						  connector_sta
> > > > > > tus_disc
> > > > > > onnected;
> > > > > > +
> > > > > > +	if (event < 0)
> > > > > 
> > > > > event is always > 0, isn't it?
> > > > > 
> > > > 
> > > > Hello CK,
> > > > 
> > > > ok, I will move this to dp patch.
> > > > 
> > > > > > +		return IRQ_HANDLED;
> > > > > > +
> > > > > > +	if (mtk_dp->drm_dev) {
> > > > > > +		dev_info(mtk_dp->dev,
> > > > > > "drm_helper_hpd_irq_event\n");
> > > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > > 
> > > > > I think this ISR would come once. If bridge has not attached,
> > > > > the
> > > > > drm
> > > > > core would lost this event. Maybe you should enable eDP
> > > > > hardware
> > > > > after
> > > > > bridge attached or send this event when attached.
> > > > > 
> > > > 
> > > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > > for dp patch, I will add it back.
> > > 
> > > I find out that mtk_dp_poweron() is in top of
> > > mtk_dp_bridge_attach().
> > > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > > mtk_dp-
> > > > drm_dev would not be NULL here. So we could drop this checking.
> > > > 
> > 
> > Hello CK,
> > 
> > If we failed to setup phy(ret!=0), we alos need to deattach this
> > bridge.
> > I don't think  it's a good idea just for remove this.
> 
> OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
> bottom of mtk_dp_bridge_attach(). irq is not part of power.
> 

I will do this and drop "if (mtk_dp->drm_dev)"

> > 
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > > 
> > > > > Executing this thread imply cable_state_change = true, so
> > > > > drop
> > > > > cable_state_change.
> > > > > 
> > > > 
> > > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > > interrupt
> > > > to
> > > > source device. it's not about connected status, so I think we
> > > > still
> > > > need this.
> > > 
> > > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > > 
> > > +	train_info->cable_state_change = true;
> > > +
> > > +	return IRQ_WAKE_THREAD;
> > > 
> > > This thread is called only when return IRQ_WAKE_THREAD, and
> > > before
> > > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > > set
> > > to
> > > true. So in this thread, train_info->cable_state_change must be
> > > true.
> > > 
> > 
> > As mentioned, this irq handler function is not only for connected
> > status.
> > 
> > this could be return if this irq is interrupt from sink device.
> > +	if (!(train_info->irq_status &
> > +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> > +		return IRQ_HANDLED;
> 
> According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
> IRQ_HANDLED would not wake up thread.
> 
> [1] 
> 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html
> 
> Regards,
> CK
> 

yes, you are right. I will return IRQ_WAKE_THREAD for handle sink
interrupt.

> > 
> > BRs,
> > Bo-Chen
> > > Regards,
> > > CK
> > > 
> > > > 
> > > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > > +
> > > > > > +		mtk_dp->train_state =
> > > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > > +
> > > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > > 
> > > > > I do not like two variable to present one thing. If
> > > > > 
> > > > > mtk_dp->train_info.cable_plugged_in = false
> > > > > and
> > > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > > 
> > > > > What does this mean? I think this mean 'now' is connected
> > > > > because
> > > > > cable_plugged_in is old information and mtk_dp_plug_state()
> > > > > is
> > > > > current
> > > > > information.
> > > > > 
> > > > > But I would like to keep cable_plugged_in and drop
> > > > > mtk_dp_plug_state()
> > > > > because cable_plugged_in would be changed in isr and it would
> > > > > be
> > > > > the
> > > > > same as mtk_dp_plug_state().
> > > > > 
> > > > > Regards,
> > > > > CK
> > > > > 
> > > > 
> > > > ok, I will drop this.
> > > > 
> > > > BRs,
> > > > Rex
> > > > 
> > > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > > +
> > > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > > +			if (mtk_dp->has_fec)
> > > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > > false);
> > > > > > +
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +		} else {
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL_LA
> > > > > > NE,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > > buf);
> > > > > > +			mtk_dp->train_info.link_rate =
> > > > > > +				min_t(int, mtk_dp-
> > > > > > > max_linkrate,
> > > > > > 
> > > > > > +				      buf[mtk_dp-
> > > > > > > max_linkrate]);
> > > > > > 
> > > > > > +			mtk_dp->train_info.lane_count =
> > > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > > +				      drm_dp_max_lane_count(buf
> > > > > > ));
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > > +		mtk_dp->train_info.irq_status &=
> > > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > > +	}
> > > > > > +
> > > > > > +	return IRQ_HANDLED;
> > > > > > +}
> > > > > > +
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 11:52               ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 11:52 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 17:15 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 16:43 +0800, Rex-BC Chen wrote:
> > On Wed, 2022-06-08 at 10:23 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Tue, 2022-06-07 at 20:24 +0800, Rex-BC Chen wrote:
> > > > On Tue, 2022-06-07 at 14:21 +0800, CK Hu wrote:
> > > > > Hi, Rex:
> > > > > 
> > > > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > 
> > > > > > This patch adds a DisplayPort driver for the Mediatek
> > > > > > mt8195
> > > > > > SoC.
> > > > > > 
> > > > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > > > offers
> > > > > > 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 <jason-jh.lin@mediatek.com>.
> > > > > > 
> > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > > > ---
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > > +
> > > > > > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void
> > > > > > *dev)
> > > > > > +{
> > > > > > +	struct mtk_dp *mtk_dp = dev;
> > > > > > +	int event;
> > > > > > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > > > > > +
> > > > > > +	event = mtk_dp_plug_state(mtk_dp) ?
> > > > > > connector_status_connected
> > > > > > :
> > > > > > +						  connector_sta
> > > > > > tus_disc
> > > > > > onnected;
> > > > > > +
> > > > > > +	if (event < 0)
> > > > > 
> > > > > event is always > 0, isn't it?
> > > > > 
> > > > 
> > > > Hello CK,
> > > > 
> > > > ok, I will move this to dp patch.
> > > > 
> > > > > > +		return IRQ_HANDLED;
> > > > > > +
> > > > > > +	if (mtk_dp->drm_dev) {
> > > > > > +		dev_info(mtk_dp->dev,
> > > > > > "drm_helper_hpd_irq_event\n");
> > > > > > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > > > > 
> > > > > I think this ISR would come once. If bridge has not attached,
> > > > > the
> > > > > drm
> > > > > core would lost this event. Maybe you should enable eDP
> > > > > hardware
> > > > > after
> > > > > bridge attached or send this event when attached.
> > > > > 
> > > > 
> > > > for edp patch, I will move it to (mtk_dp_bridge_attach).
> > > > for dp patch, I will add it back.
> > > 
> > > I find out that mtk_dp_poweron() is in top of
> > > mtk_dp_bridge_attach().
> > > If move mtk_dp_poweron() to bottom of mtk_dp_bridge_attach(),
> > > mtk_dp-
> > > > drm_dev would not be NULL here. So we could drop this checking.
> > > > 
> > 
> > Hello CK,
> > 
> > If we failed to setup phy(ret!=0), we alos need to deattach this
> > bridge.
> > I don't think  it's a good idea just for remove this.
> 
> OK, move mtk_dp_hwirq_enable() out of mtk_dp_poweron() and to the
> bottom of mtk_dp_bridge_attach(). irq is not part of power.
> 

I will do this and drop "if (mtk_dp->drm_dev)"

> > 
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.cable_state_change) {
> > > > > 
> > > > > Executing this thread imply cable_state_change = true, so
> > > > > drop
> > > > > cable_state_change.
> > > > > 
> > > > 
> > > > In mtk_dp_hpd_isr_handler(), there is another irq
> > > > "MTK_DP_HPD_INTERRUPT" which means the sink devices give a
> > > > interrupt
> > > > to
> > > > source device. it's not about connected status, so I think we
> > > > still
> > > > need this.
> > > 
> > > In bottom of mtk_dp_hpd_isr_handler(), the code is:
> > > 
> > > +	train_info->cable_state_change = true;
> > > +
> > > +	return IRQ_WAKE_THREAD;
> > > 
> > > This thread is called only when return IRQ_WAKE_THREAD, and
> > > before
> > > return IRQ_WAKE_THREAD, train_info->cable_state_change is always
> > > set
> > > to
> > > true. So in this thread, train_info->cable_state_change must be
> > > true.
> > > 
> > 
> > As mentioned, this irq handler function is not only for connected
> > status.
> > 
> > this could be return if this irq is interrupt from sink device.
> > +	if (!(train_info->irq_status &
> > +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> > +		return IRQ_HANDLED;
> 
> According to [1], return IRQ_WAKE_THREAD to wake up thread. So return
> IRQ_HANDLED would not wake up thread.
> 
> [1] 
> 
https://www.kernel.org/doc/htmldocs/kernel-api/API-request-threaded-irq.html
> 
> Regards,
> CK
> 

yes, you are right. I will return IRQ_WAKE_THREAD for handle sink
interrupt.

> > 
> > BRs,
> > Bo-Chen
> > > Regards,
> > > CK
> > > 
> > > > 
> > > > > > +		mtk_dp->train_info.cable_state_change = false;
> > > > > > +
> > > > > > +		mtk_dp->train_state =
> > > > > > MTK_DP_TRAIN_STATE_STARTUP;
> > > > > > +
> > > > > > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > > > > > +		    !mtk_dp_plug_state(mtk_dp)) {
> > > > > 
> > > > > I do not like two variable to present one thing. If
> > > > > 
> > > > > mtk_dp->train_info.cable_plugged_in = false
> > > > > and
> > > > > mtk_dp_plug_state(mtk_dp) = ture
> > > > > 
> > > > > What does this mean? I think this mean 'now' is connected
> > > > > because
> > > > > cable_plugged_in is old information and mtk_dp_plug_state()
> > > > > is
> > > > > current
> > > > > information.
> > > > > 
> > > > > But I would like to keep cable_plugged_in and drop
> > > > > mtk_dp_plug_state()
> > > > > because cable_plugged_in would be changed in isr and it would
> > > > > be
> > > > > the
> > > > > same as mtk_dp_plug_state().
> > > > > 
> > > > > Regards,
> > > > > CK
> > > > > 
> > > > 
> > > > ok, I will drop this.
> > > > 
> > > > BRs,
> > > > Rex
> > > > 
> > > > > > +			mtk_dp_video_mute(mtk_dp, true);
> > > > > > +
> > > > > > +			mtk_dp_initialize_priv_data(mtk_dp);
> > > > > > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > > > > > +			if (mtk_dp->has_fec)
> > > > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > > > false);
> > > > > > +
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +		} else {
> > > > > > +			mtk_dp_update_bits(mtk_dp,
> > > > > > MTK_DP_TOP_PWR_STATE,
> > > > > > +					   DP_PWR_STATE_BANDGAP
> > > > > > _TPLL_LA
> > > > > > NE,
> > > > > > +					   DP_PWR_STATE_MASK);
> > > > > > +			drm_dp_read_dpcd_caps(&mtk_dp->aux,
> > > > > > buf);
> > > > > > +			mtk_dp->train_info.link_rate =
> > > > > > +				min_t(int, mtk_dp-
> > > > > > > max_linkrate,
> > > > > > 
> > > > > > +				      buf[mtk_dp-
> > > > > > > max_linkrate]);
> > > > > > 
> > > > > > +			mtk_dp->train_info.lane_count =
> > > > > > +				min_t(int, mtk_dp->max_lanes,
> > > > > > +				      drm_dp_max_lane_count(buf
> > > > > > ));
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	if (mtk_dp->train_info.irq_status &
> > > > > > MTK_DP_HPD_INTERRUPT) {
> > > > > > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > > > > > +		mtk_dp->train_info.irq_status &=
> > > > > > ~MTK_DP_HPD_INTERRUPT;
> > > > > > +		mtk_dp_hpd_sink_event(mtk_dp);
> > > > > > +	}
> > > > > > +
> > > > > > +	return IRQ_HANDLED;
> > > > > > +}
> > > > > > +
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-08  2:44         ` CK Hu
                             ` (2 preceding siblings ...)
  (?)
@ 2022-06-08 12:54           ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 12:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 10:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	bool training_done = false;
> > > > +	short max_retry = 50;
> > > > +	int ret = 0;
> > > > +
> > > > +	do {
> > > > +		switch (mtk_dp->train_state) {
> > > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > > 
> > > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > > even
> > > though HPD ISR does not exist. Does this mean HPD ISR is
> > > redundant?
> > > If
> > > HPD ISR is not redundant, create a new state
> > > MTK_DP_TRAIN_STATE_NONE
> > > for init state.
> > > 
> > 
> > Hello CK,
> > 
> > I think we don't need MTK_DP_TRAIN_STATE_NONE.
> > Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> > start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".
> 
> The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
> change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state
> change
> in HPD thread.
> 

ok, in edp it's redundant in mtk_dp_hpd_event_thread(), but I will add
it back in dp patch.

> > 
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > > +			if (mtk_dp_parse_capabilities(mtk_dp))
> > > > {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count = 0;
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > > +			} else {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count++;
> > > > +
> > > > +				if (mtk_dp-
> > > > >train_info.check_cap_count
> > > > > 
> > > > 
> > > > +				    MTK_DP_CHECK_SINK_CAP_TIMEO
> > > > UT_COUNT
> > > > ) {
> > > > +					mtk_dp-
> > > > > train_info.check_cap_count = 0;
> > > > 
> > > > +					mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +					ret = -ETIMEDOUT;
> > > > +				}
> > > > +			}
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > 
> > > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > > 
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > > +			ret = mtk_dp_train_start(mtk_dp);
> > > > +			if (ret == 0) {
> > > > +				mtk_dp_video_mute(mtk_dp,
> > > > true);
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_NORMAL;
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > mtk_dp-
> > > > > has_fec);
> > > > 
> > > > +			} else if (ret != -EAGAIN) {
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +			}
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			training_done = true;
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > > 
> > > When would this case happen?
> > > 
> > > Regards,
> > > CK
> > 
> > Yes, if it's disconnected if we are still training for dp.
> > or failed to training min spec RBR.
> 
> I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it
> would
> jump out of this loop and would not get into this loop, so this case
> would never get in. This is redundant, so remove this.
> 
> Regards,
> CK
> 

ok, I will remove it

BRs,
Bo-Chen

> > 
> > BRs,
> > Rex
> > > 
> > > > +			break;
> > > > +		default:
> > > > +			break;
> > > > +		}
> > > > +
> > > > +		if (ret) {
> > > > +			if (ret == -EAGAIN)
> > > > +				continue;
> > > > +			/*
> > > > +			 * If we get any other error number, it
> > > > doesn't
> > > > +			 * make any sense to keep iterating.
> > > > +			 */
> > > > +			break;
> > > > +		}
> > > > +	} while (!training_done || --max_retry);
> > > > +
> > > > +	return ret;
> > > > +}
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 12:54           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 12:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-06-08 at 10:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	bool training_done = false;
> > > > +	short max_retry = 50;
> > > > +	int ret = 0;
> > > > +
> > > > +	do {
> > > > +		switch (mtk_dp->train_state) {
> > > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > > 
> > > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > > even
> > > though HPD ISR does not exist. Does this mean HPD ISR is
> > > redundant?
> > > If
> > > HPD ISR is not redundant, create a new state
> > > MTK_DP_TRAIN_STATE_NONE
> > > for init state.
> > > 
> > 
> > Hello CK,
> > 
> > I think we don't need MTK_DP_TRAIN_STATE_NONE.
> > Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> > start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".
> 
> The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
> change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state
> change
> in HPD thread.
> 

ok, in edp it's redundant in mtk_dp_hpd_event_thread(), but I will add
it back in dp patch.

> > 
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > > +			if (mtk_dp_parse_capabilities(mtk_dp))
> > > > {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count = 0;
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > > +			} else {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count++;
> > > > +
> > > > +				if (mtk_dp-
> > > > >train_info.check_cap_count
> > > > > 
> > > > 
> > > > +				    MTK_DP_CHECK_SINK_CAP_TIMEO
> > > > UT_COUNT
> > > > ) {
> > > > +					mtk_dp-
> > > > > train_info.check_cap_count = 0;
> > > > 
> > > > +					mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +					ret = -ETIMEDOUT;
> > > > +				}
> > > > +			}
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > 
> > > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > > 
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > > +			ret = mtk_dp_train_start(mtk_dp);
> > > > +			if (ret == 0) {
> > > > +				mtk_dp_video_mute(mtk_dp,
> > > > true);
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_NORMAL;
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > mtk_dp-
> > > > > has_fec);
> > > > 
> > > > +			} else if (ret != -EAGAIN) {
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +			}
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			training_done = true;
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > > 
> > > When would this case happen?
> > > 
> > > Regards,
> > > CK
> > 
> > Yes, if it's disconnected if we are still training for dp.
> > or failed to training min spec RBR.
> 
> I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it
> would
> jump out of this loop and would not get into this loop, so this case
> would never get in. This is redundant, so remove this.
> 
> Regards,
> CK
> 

ok, I will remove it

BRs,
Bo-Chen

> > 
> > BRs,
> > Rex
> > > 
> > > > +			break;
> > > > +		default:
> > > > +			break;
> > > > +		}
> > > > +
> > > > +		if (ret) {
> > > > +			if (ret == -EAGAIN)
> > > > +				continue;
> > > > +			/*
> > > > +			 * If we get any other error number, it
> > > > doesn't
> > > > +			 * make any sense to keep iterating.
> > > > +			 */
> > > > +			break;
> > > > +		}
> > > > +	} while (!training_done || --max_retry);
> > > > +
> > > > +	return ret;
> > > > +}
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 12:54           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 12:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 10:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	bool training_done = false;
> > > > +	short max_retry = 50;
> > > > +	int ret = 0;
> > > > +
> > > > +	do {
> > > > +		switch (mtk_dp->train_state) {
> > > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > > 
> > > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > > even
> > > though HPD ISR does not exist. Does this mean HPD ISR is
> > > redundant?
> > > If
> > > HPD ISR is not redundant, create a new state
> > > MTK_DP_TRAIN_STATE_NONE
> > > for init state.
> > > 
> > 
> > Hello CK,
> > 
> > I think we don't need MTK_DP_TRAIN_STATE_NONE.
> > Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> > start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".
> 
> The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
> change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state
> change
> in HPD thread.
> 

ok, in edp it's redundant in mtk_dp_hpd_event_thread(), but I will add
it back in dp patch.

> > 
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > > +			if (mtk_dp_parse_capabilities(mtk_dp))
> > > > {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count = 0;
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > > +			} else {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count++;
> > > > +
> > > > +				if (mtk_dp-
> > > > >train_info.check_cap_count
> > > > > 
> > > > 
> > > > +				    MTK_DP_CHECK_SINK_CAP_TIMEO
> > > > UT_COUNT
> > > > ) {
> > > > +					mtk_dp-
> > > > > train_info.check_cap_count = 0;
> > > > 
> > > > +					mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +					ret = -ETIMEDOUT;
> > > > +				}
> > > > +			}
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > 
> > > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > > 
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > > +			ret = mtk_dp_train_start(mtk_dp);
> > > > +			if (ret == 0) {
> > > > +				mtk_dp_video_mute(mtk_dp,
> > > > true);
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_NORMAL;
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > mtk_dp-
> > > > > has_fec);
> > > > 
> > > > +			} else if (ret != -EAGAIN) {
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +			}
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			training_done = true;
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > > 
> > > When would this case happen?
> > > 
> > > Regards,
> > > CK
> > 
> > Yes, if it's disconnected if we are still training for dp.
> > or failed to training min spec RBR.
> 
> I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it
> would
> jump out of this loop and would not get into this loop, so this case
> would never get in. This is redundant, so remove this.
> 
> Regards,
> CK
> 

ok, I will remove it

BRs,
Bo-Chen

> > 
> > BRs,
> > Rex
> > > 
> > > > +			break;
> > > > +		default:
> > > > +			break;
> > > > +		}
> > > > +
> > > > +		if (ret) {
> > > > +			if (ret == -EAGAIN)
> > > > +				continue;
> > > > +			/*
> > > > +			 * If we get any other error number, it
> > > > doesn't
> > > > +			 * make any sense to keep iterating.
> > > > +			 */
> > > > +			break;
> > > > +		}
> > > > +	} while (!training_done || --max_retry);
> > > > +
> > > > +	return ret;
> > > > +}
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 12:54           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 12:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 10:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	bool training_done = false;
> > > > +	short max_retry = 50;
> > > > +	int ret = 0;
> > > > +
> > > > +	do {
> > > > +		switch (mtk_dp->train_state) {
> > > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > > 
> > > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > > even
> > > though HPD ISR does not exist. Does this mean HPD ISR is
> > > redundant?
> > > If
> > > HPD ISR is not redundant, create a new state
> > > MTK_DP_TRAIN_STATE_NONE
> > > for init state.
> > > 
> > 
> > Hello CK,
> > 
> > I think we don't need MTK_DP_TRAIN_STATE_NONE.
> > Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> > start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".
> 
> The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
> change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state
> change
> in HPD thread.
> 

ok, in edp it's redundant in mtk_dp_hpd_event_thread(), but I will add
it back in dp patch.

> > 
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > > +			if (mtk_dp_parse_capabilities(mtk_dp))
> > > > {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count = 0;
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > > +			} else {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count++;
> > > > +
> > > > +				if (mtk_dp-
> > > > >train_info.check_cap_count
> > > > > 
> > > > 
> > > > +				    MTK_DP_CHECK_SINK_CAP_TIMEO
> > > > UT_COUNT
> > > > ) {
> > > > +					mtk_dp-
> > > > > train_info.check_cap_count = 0;
> > > > 
> > > > +					mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +					ret = -ETIMEDOUT;
> > > > +				}
> > > > +			}
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > 
> > > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > > 
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > > +			ret = mtk_dp_train_start(mtk_dp);
> > > > +			if (ret == 0) {
> > > > +				mtk_dp_video_mute(mtk_dp,
> > > > true);
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_NORMAL;
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > mtk_dp-
> > > > > has_fec);
> > > > 
> > > > +			} else if (ret != -EAGAIN) {
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +			}
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			training_done = true;
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > > 
> > > When would this case happen?
> > > 
> > > Regards,
> > > CK
> > 
> > Yes, if it's disconnected if we are still training for dp.
> > or failed to training min spec RBR.
> 
> I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it
> would
> jump out of this loop and would not get into this loop, so this case
> would never get in. This is redundant, so remove this.
> 
> Regards,
> CK
> 

ok, I will remove it

BRs,
Bo-Chen

> > 
> > BRs,
> > Rex
> > > 
> > > > +			break;
> > > > +		default:
> > > > +			break;
> > > > +		}
> > > > +
> > > > +		if (ret) {
> > > > +			if (ret == -EAGAIN)
> > > > +				continue;
> > > > +			/*
> > > > +			 * If we get any other error number, it
> > > > doesn't
> > > > +			 * make any sense to keep iterating.
> > > > +			 */
> > > > +			break;
> > > > +		}
> > > > +	} while (!training_done || --max_retry);
> > > > +
> > > > +	return ret;
> > > > +}
> > > 
> > > 
> > 
> > 
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-08 12:54           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-08 12:54 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 10:44 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Tue, 2022-06-07 at 20:44 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 14:44 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	bool training_done = false;
> > > > +	short max_retry = 50;
> > > > +	int ret = 0;
> > > > +
> > > > +	do {
> > > > +		switch (mtk_dp->train_state) {
> > > > +		case MTK_DP_TRAIN_STATE_STARTUP:
> > > 
> > > mtk_dp->train_state is initialized as MTK_DP_TRAIN_STATE_STARTUP
> > > even
> > > though HPD ISR does not exist. Does this mean HPD ISR is
> > > redundant?
> > > If
> > > HPD ISR is not redundant, create a new state
> > > MTK_DP_TRAIN_STATE_NONE
> > > for init state.
> > > 
> > 
> > Hello CK,
> > 
> > I think we don't need MTK_DP_TRAIN_STATE_NONE.
> > Because it's "DP_TRAIN_STATE" not "DP_STATE", I think it's ok if we
> > start this state machine with "MTK_DP_TRAIN_STATE_STARTUP".
> 
> The initial state is MTK_DP_TRAIN_STATE_STARTUP, and HPD thread would
> change state from MTK_DP_TRAIN_STATE_STARTUP to
> MTK_DP_TRAIN_STATE_STARTUP, this is redundant. So drop the state
> change
> in HPD thread.
> 

ok, in edp it's redundant in mtk_dp_hpd_event_thread(), but I will add
it back in dp patch.

> > 
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKCAP;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKCAP:
> > > > +			if (mtk_dp_parse_capabilities(mtk_dp))
> > > > {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count = 0;
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > > +			} else {
> > > > +				mtk_dp-
> > > > >train_info.check_cap_count++;
> > > > +
> > > > +				if (mtk_dp-
> > > > >train_info.check_cap_count
> > > > > 
> > > > 
> > > > +				    MTK_DP_CHECK_SINK_CAP_TIMEO
> > > > UT_COUNT
> > > > ) {
> > > > +					mtk_dp-
> > > > > train_info.check_cap_count = 0;
> > > > 
> > > > +					mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +					ret = -ETIMEDOUT;
> > > > +				}
> > > > +			}
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_CHECKEDID:
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > 
> > > MTK_DP_TRAIN_STATE_CHECKEDID is a redundant state, drop it.
> > > 
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING;
> > > > +			break;
> > > > +
> > > > +		case MTK_DP_TRAIN_STATE_TRAINING:
> > > > +			ret = mtk_dp_train_start(mtk_dp);
> > > > +			if (ret == 0) {
> > > > +				mtk_dp_video_mute(mtk_dp,
> > > > true);
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_NORMAL;
> > > > +				mtk_dp_fec_enable(mtk_dp,
> > > > mtk_dp-
> > > > > has_fec);
> > > > 
> > > > +			} else if (ret != -EAGAIN) {
> > > > +				mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_DPIDLE;
> > > > +			}
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_NORMAL:
> > > > +			mtk_dp_state_handler(mtk_dp);
> > > > +			training_done = true;
> > > > +			break;
> > > > +		case MTK_DP_TRAIN_STATE_DPIDLE:
> > > 
> > > When would this case happen?
> > > 
> > > Regards,
> > > CK
> > 
> > Yes, if it's disconnected if we are still training for dp.
> > or failed to training min spec RBR.
> 
> I mean, every time state change to MTK_DP_TRAIN_STATE_DPIDLE, it
> would
> jump out of this loop and would not get into this loop, so this case
> would never get in. This is redundant, so remove this.
> 
> Regards,
> CK
> 

ok, I will remove it

BRs,
Bo-Chen

> > 
> > BRs,
> > Rex
> > > 
> > > > +			break;
> > > > +		default:
> > > > +			break;
> > > > +		}
> > > > +
> > > > +		if (ret) {
> > > > +			if (ret == -EAGAIN)
> > > > +				continue;
> > > > +			/*
> > > > +			 * If we get any other error number, it
> > > > doesn't
> > > > +			 * make any sense to keep iterating.
> > > > +			 */
> > > > +			break;
> > > > +		}
> > > > +	} while (!training_done || --max_retry);
> > > > +
> > > > +	return ret;
> > > > +}
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-08 16:31     ` Vinod Koul
  -1 siblings, 0 replies; 450+ messages in thread
From: Vinod Koul @ 2022-06-08 16:31 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Helge Deller, CK Hu, Jitao shi,
	Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On 23-05-22, 12:47, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.

I must admit that I have missed previous iteration of this driver. This
is a standalone phy driver, pls split and submit this and we can get
this merged...

> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  MAINTAINERS                       |   1 +
>  drivers/phy/mediatek/Kconfig      |   8 ++
>  drivers/phy/mediatek/Makefile     |   1 +
>  drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
>  4 files changed, 210 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4cc47b2dbdc9..bfca96469d80 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek DisplayPort PHY driver
> + *
> + * Copyright (c) 2021 BayLibre

2022 now

> + * Author: Markus Schneider-Pargmann <msp@baylibre.com>

use MODULE_AUTHOR()

> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define PHY_OFFSET 0x1000
> +
> +#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
> +#define TPLL_SSC_EN					BIT(3)
> +
> +#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
> +#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 + 0x38)
> +#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)

Sound like BIT(10) and BIT (12), no?

> +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
> +#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)

Here too

> +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
> +#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
> +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
> +#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
> +#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
> +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> +
> +struct mtk_dp_phy {
> +	struct regmap *regs;
> +};
> +
> +static int mtk_dp_phy_init(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 driving_params[] = {
> +		DRIVING_PARAM_3_DEFAULT,
> +		DRIVING_PARAM_4_DEFAULT,
> +		DRIVING_PARAM_5_DEFAULT,
> +		DRIVING_PARAM_6_DEFAULT,
> +		DRIVING_PARAM_7_DEFAULT,
> +		DRIVING_PARAM_8_DEFAULT
> +	};
> +
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 val;
> +
> +	if (opts->dp.set_rate) {
> +		switch (opts->dp.link_rate) {
> +		default:
> +			dev_err(&phy->dev,
> +				"Implementation error, unknown linkrate %x\n",
> +				opts->dp.link_rate);
> +			return -EINVAL;
> +		case 1620:
> +			val = BIT_RATE_RBR;
> +			break;
> +		case 2700:
> +			val = BIT_RATE_HBR;
> +			break;
> +		case 5400:
> +			val = BIT_RATE_HBR2;
> +			break;
> +		case 8100:
> +			val = BIT_RATE_HBR3;
> +			break;
> +		}
> +		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> +	}
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> +			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_reset(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 0);
> +	usleep_range(50, 200);
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 1);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_dp_phy_dev_ops = {
> +	.init = mtk_dp_phy_init,
> +	.configure = mtk_dp_phy_configure,
> +	.reset = mtk_dp_phy_reset,
> +	.owner = THIS_MODULE,
> +};
> +
> +static int mtk_dp_phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_dp_phy *dp_phy;
> +	struct phy *phy;
> +	struct regmap *regs;
> +
> +	regs = *(struct regmap **)dev->platform_data;
> +	if (!regs)
> +		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
> +
> +	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> +	if (!dp_phy)
> +		return -ENOMEM;
> +
> +	dp_phy->regs = regs;
> +	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
> +
> +	phy_set_drvdata(phy, dp_phy);
> +	if (!dev->of_node)
> +		phy_create_lookup(phy, "dp", dev_name(dev));
> +
> +	return 0;
> +}
> +
> +struct platform_driver mtk_dp_phy_driver = {
> +	.probe = mtk_dp_phy_probe,
> +	.driver = {
> +		.name = "mediatek-dp-phy",
> +	},
> +};
> +module_platform_driver(mtk_dp_phy_driver);
> +
> +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.35.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
@ 2022-06-08 16:31     ` Vinod Koul
  0 siblings, 0 replies; 450+ messages in thread
From: Vinod Koul @ 2022-06-08 16:31 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: linux-fbdev, devicetree, David Airlie, dri-devel,
	Krzysztof Kozlowski, linux-phy, Helge Deller,
	Kishon Vijay Abraham I, Chunfeng Yun, Chun-Kuang Hu, Jitao shi,
	Thomas Zimmermann, Markus Schneider-Pargmann, Rob Herring,
	linux-mediatek, Matthias Brugger, linux-arm-kernel, linux-kernel

On 23-05-22, 12:47, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.

I must admit that I have missed previous iteration of this driver. This
is a standalone phy driver, pls split and submit this and we can get
this merged...

> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  MAINTAINERS                       |   1 +
>  drivers/phy/mediatek/Kconfig      |   8 ++
>  drivers/phy/mediatek/Makefile     |   1 +
>  drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
>  4 files changed, 210 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4cc47b2dbdc9..bfca96469d80 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek DisplayPort PHY driver
> + *
> + * Copyright (c) 2021 BayLibre

2022 now

> + * Author: Markus Schneider-Pargmann <msp@baylibre.com>

use MODULE_AUTHOR()

> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define PHY_OFFSET 0x1000
> +
> +#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
> +#define TPLL_SSC_EN					BIT(3)
> +
> +#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
> +#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 + 0x38)
> +#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)

Sound like BIT(10) and BIT (12), no?

> +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
> +#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)

Here too

> +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
> +#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
> +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
> +#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
> +#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
> +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> +
> +struct mtk_dp_phy {
> +	struct regmap *regs;
> +};
> +
> +static int mtk_dp_phy_init(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 driving_params[] = {
> +		DRIVING_PARAM_3_DEFAULT,
> +		DRIVING_PARAM_4_DEFAULT,
> +		DRIVING_PARAM_5_DEFAULT,
> +		DRIVING_PARAM_6_DEFAULT,
> +		DRIVING_PARAM_7_DEFAULT,
> +		DRIVING_PARAM_8_DEFAULT
> +	};
> +
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 val;
> +
> +	if (opts->dp.set_rate) {
> +		switch (opts->dp.link_rate) {
> +		default:
> +			dev_err(&phy->dev,
> +				"Implementation error, unknown linkrate %x\n",
> +				opts->dp.link_rate);
> +			return -EINVAL;
> +		case 1620:
> +			val = BIT_RATE_RBR;
> +			break;
> +		case 2700:
> +			val = BIT_RATE_HBR;
> +			break;
> +		case 5400:
> +			val = BIT_RATE_HBR2;
> +			break;
> +		case 8100:
> +			val = BIT_RATE_HBR3;
> +			break;
> +		}
> +		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> +	}
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> +			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_reset(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 0);
> +	usleep_range(50, 200);
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 1);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_dp_phy_dev_ops = {
> +	.init = mtk_dp_phy_init,
> +	.configure = mtk_dp_phy_configure,
> +	.reset = mtk_dp_phy_reset,
> +	.owner = THIS_MODULE,
> +};
> +
> +static int mtk_dp_phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_dp_phy *dp_phy;
> +	struct phy *phy;
> +	struct regmap *regs;
> +
> +	regs = *(struct regmap **)dev->platform_data;
> +	if (!regs)
> +		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
> +
> +	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> +	if (!dp_phy)
> +		return -ENOMEM;
> +
> +	dp_phy->regs = regs;
> +	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
> +
> +	phy_set_drvdata(phy, dp_phy);
> +	if (!dev->of_node)
> +		phy_create_lookup(phy, "dp", dev_name(dev));
> +
> +	return 0;
> +}
> +
> +struct platform_driver mtk_dp_phy_driver = {
> +	.probe = mtk_dp_phy_probe,
> +	.driver = {
> +		.name = "mediatek-dp-phy",
> +	},
> +};
> +module_platform_driver(mtk_dp_phy_driver);
> +
> +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.35.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
@ 2022-06-08 16:31     ` Vinod Koul
  0 siblings, 0 replies; 450+ messages in thread
From: Vinod Koul @ 2022-06-08 16:31 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Helge Deller, CK Hu, Jitao shi,
	Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On 23-05-22, 12:47, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.

I must admit that I have missed previous iteration of this driver. This
is a standalone phy driver, pls split and submit this and we can get
this merged...

> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  MAINTAINERS                       |   1 +
>  drivers/phy/mediatek/Kconfig      |   8 ++
>  drivers/phy/mediatek/Makefile     |   1 +
>  drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
>  4 files changed, 210 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4cc47b2dbdc9..bfca96469d80 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek DisplayPort PHY driver
> + *
> + * Copyright (c) 2021 BayLibre

2022 now

> + * Author: Markus Schneider-Pargmann <msp@baylibre.com>

use MODULE_AUTHOR()

> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define PHY_OFFSET 0x1000
> +
> +#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
> +#define TPLL_SSC_EN					BIT(3)
> +
> +#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
> +#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 + 0x38)
> +#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)

Sound like BIT(10) and BIT (12), no?

> +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
> +#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)

Here too

> +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
> +#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
> +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
> +#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
> +#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
> +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> +
> +struct mtk_dp_phy {
> +	struct regmap *regs;
> +};
> +
> +static int mtk_dp_phy_init(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 driving_params[] = {
> +		DRIVING_PARAM_3_DEFAULT,
> +		DRIVING_PARAM_4_DEFAULT,
> +		DRIVING_PARAM_5_DEFAULT,
> +		DRIVING_PARAM_6_DEFAULT,
> +		DRIVING_PARAM_7_DEFAULT,
> +		DRIVING_PARAM_8_DEFAULT
> +	};
> +
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 val;
> +
> +	if (opts->dp.set_rate) {
> +		switch (opts->dp.link_rate) {
> +		default:
> +			dev_err(&phy->dev,
> +				"Implementation error, unknown linkrate %x\n",
> +				opts->dp.link_rate);
> +			return -EINVAL;
> +		case 1620:
> +			val = BIT_RATE_RBR;
> +			break;
> +		case 2700:
> +			val = BIT_RATE_HBR;
> +			break;
> +		case 5400:
> +			val = BIT_RATE_HBR2;
> +			break;
> +		case 8100:
> +			val = BIT_RATE_HBR3;
> +			break;
> +		}
> +		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> +	}
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> +			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_reset(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 0);
> +	usleep_range(50, 200);
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 1);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_dp_phy_dev_ops = {
> +	.init = mtk_dp_phy_init,
> +	.configure = mtk_dp_phy_configure,
> +	.reset = mtk_dp_phy_reset,
> +	.owner = THIS_MODULE,
> +};
> +
> +static int mtk_dp_phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_dp_phy *dp_phy;
> +	struct phy *phy;
> +	struct regmap *regs;
> +
> +	regs = *(struct regmap **)dev->platform_data;
> +	if (!regs)
> +		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
> +
> +	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> +	if (!dp_phy)
> +		return -ENOMEM;
> +
> +	dp_phy->regs = regs;
> +	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
> +
> +	phy_set_drvdata(phy, dp_phy);
> +	if (!dev->of_node)
> +		phy_create_lookup(phy, "dp", dev_name(dev));
> +
> +	return 0;
> +}
> +
> +struct platform_driver mtk_dp_phy_driver = {
> +	.probe = mtk_dp_phy_probe,
> +	.driver = {
> +		.name = "mediatek-dp-phy",
> +	},
> +};
> +module_platform_driver(mtk_dp_phy_driver);
> +
> +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.35.1

-- 
~Vinod

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
@ 2022-06-08 16:31     ` Vinod Koul
  0 siblings, 0 replies; 450+ messages in thread
From: Vinod Koul @ 2022-06-08 16:31 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Helge Deller, CK Hu, Jitao shi,
	Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On 23-05-22, 12:47, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.

I must admit that I have missed previous iteration of this driver. This
is a standalone phy driver, pls split and submit this and we can get
this merged...

> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  MAINTAINERS                       |   1 +
>  drivers/phy/mediatek/Kconfig      |   8 ++
>  drivers/phy/mediatek/Makefile     |   1 +
>  drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
>  4 files changed, 210 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4cc47b2dbdc9..bfca96469d80 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek DisplayPort PHY driver
> + *
> + * Copyright (c) 2021 BayLibre

2022 now

> + * Author: Markus Schneider-Pargmann <msp@baylibre.com>

use MODULE_AUTHOR()

> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define PHY_OFFSET 0x1000
> +
> +#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
> +#define TPLL_SSC_EN					BIT(3)
> +
> +#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
> +#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 + 0x38)
> +#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)

Sound like BIT(10) and BIT (12), no?

> +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
> +#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)

Here too

> +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
> +#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
> +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
> +#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
> +#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
> +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> +
> +struct mtk_dp_phy {
> +	struct regmap *regs;
> +};
> +
> +static int mtk_dp_phy_init(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 driving_params[] = {
> +		DRIVING_PARAM_3_DEFAULT,
> +		DRIVING_PARAM_4_DEFAULT,
> +		DRIVING_PARAM_5_DEFAULT,
> +		DRIVING_PARAM_6_DEFAULT,
> +		DRIVING_PARAM_7_DEFAULT,
> +		DRIVING_PARAM_8_DEFAULT
> +	};
> +
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 val;
> +
> +	if (opts->dp.set_rate) {
> +		switch (opts->dp.link_rate) {
> +		default:
> +			dev_err(&phy->dev,
> +				"Implementation error, unknown linkrate %x\n",
> +				opts->dp.link_rate);
> +			return -EINVAL;
> +		case 1620:
> +			val = BIT_RATE_RBR;
> +			break;
> +		case 2700:
> +			val = BIT_RATE_HBR;
> +			break;
> +		case 5400:
> +			val = BIT_RATE_HBR2;
> +			break;
> +		case 8100:
> +			val = BIT_RATE_HBR3;
> +			break;
> +		}
> +		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> +	}
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> +			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_reset(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 0);
> +	usleep_range(50, 200);
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 1);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_dp_phy_dev_ops = {
> +	.init = mtk_dp_phy_init,
> +	.configure = mtk_dp_phy_configure,
> +	.reset = mtk_dp_phy_reset,
> +	.owner = THIS_MODULE,
> +};
> +
> +static int mtk_dp_phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_dp_phy *dp_phy;
> +	struct phy *phy;
> +	struct regmap *regs;
> +
> +	regs = *(struct regmap **)dev->platform_data;
> +	if (!regs)
> +		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
> +
> +	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> +	if (!dp_phy)
> +		return -ENOMEM;
> +
> +	dp_phy->regs = regs;
> +	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
> +
> +	phy_set_drvdata(phy, dp_phy);
> +	if (!dev->of_node)
> +		phy_create_lookup(phy, "dp", dev_name(dev));
> +
> +	return 0;
> +}
> +
> +struct platform_driver mtk_dp_phy_driver = {
> +	.probe = mtk_dp_phy_probe,
> +	.driver = {
> +		.name = "mediatek-dp-phy",
> +	},
> +};
> +module_platform_driver(mtk_dp_phy_driver);
> +
> +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.35.1

-- 
~Vinod

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
@ 2022-06-08 16:31     ` Vinod Koul
  0 siblings, 0 replies; 450+ messages in thread
From: Vinod Koul @ 2022-06-08 16:31 UTC (permalink / raw)
  To: Guillaume Ranquet
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Rob Herring, Krzysztof Kozlowski, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Helge Deller, CK Hu, Jitao shi,
	Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On 23-05-22, 12:47, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> 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.

I must admit that I have missed previous iteration of this driver. This
is a standalone phy driver, pls split and submit this and we can get
this merged...

> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  MAINTAINERS                       |   1 +
>  drivers/phy/mediatek/Kconfig      |   8 ++
>  drivers/phy/mediatek/Makefile     |   1 +
>  drivers/phy/mediatek/phy-mtk-dp.c | 200 ++++++++++++++++++++++++++++++
>  4 files changed, 210 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4cc47b2dbdc9..bfca96469d80 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6604,6 +6604,7 @@ L:	linux-mediatek@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 000000000000..6f29854f0c2f
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek DisplayPort PHY driver
> + *
> + * Copyright (c) 2021 BayLibre

2022 now

> + * Author: Markus Schneider-Pargmann <msp@baylibre.com>

use MODULE_AUTHOR()

> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define PHY_OFFSET 0x1000
> +
> +#define MTK_DP_PHY_DIG_PLL_CTL_1		(PHY_OFFSET + 0x14)
> +#define TPLL_SSC_EN					BIT(3)
> +
> +#define MTK_DP_PHY_DIG_BIT_RATE		(PHY_OFFSET + 0x3C)
> +#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 + 0x38)
> +#define DP_GLB_SW_RST_PHYD			BIT(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	BIT(4)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT	((BIT(2) | BIT(4)) << 8)

Sound like BIT(10) and BIT (12), no?

> +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT	GENMASK(20, 19)
> +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT	GENMASK(29, 29)
> +#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 XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT	GENMASK(4, 3)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT	GENMASK(12, 9)
> +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT	((BIT(2) | BIT(5)) << 16)

Here too

> +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT	GENMASK(29, 29)
> +#define DRIVING_PARAM_4_DEFAULT		(XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT	(BIT(3) | BIT(5))
> +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT	GENMASK(13, 12)
> +#define DRIVING_PARAM_5_DEFAULT		(XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT	GENMASK(10, 10)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT	GENMASK(19, 19)
> +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT	GENMASK(28, 28)
> +#define DRIVING_PARAM_6_DEFAULT		(XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT	0
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT	GENMASK(10, 9)
> +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT	GENMASK(19, 18)
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_7_DEFAULT		(XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> +
> +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT	GENMASK(3, 3)
> +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT	0
> +#define DRIVING_PARAM_8_DEFAULT		(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> +						 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> +
> +struct mtk_dp_phy {
> +	struct regmap *regs;
> +};
> +
> +static int mtk_dp_phy_init(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 driving_params[] = {
> +		DRIVING_PARAM_3_DEFAULT,
> +		DRIVING_PARAM_4_DEFAULT,
> +		DRIVING_PARAM_5_DEFAULT,
> +		DRIVING_PARAM_6_DEFAULT,
> +		DRIVING_PARAM_7_DEFAULT,
> +		DRIVING_PARAM_8_DEFAULT
> +	};
> +
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +	regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> +			  driving_params, ARRAY_SIZE(driving_params));
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +	u32 val;
> +
> +	if (opts->dp.set_rate) {
> +		switch (opts->dp.link_rate) {
> +		default:
> +			dev_err(&phy->dev,
> +				"Implementation error, unknown linkrate %x\n",
> +				opts->dp.link_rate);
> +			return -EINVAL;
> +		case 1620:
> +			val = BIT_RATE_RBR;
> +			break;
> +		case 2700:
> +			val = BIT_RATE_HBR;
> +			break;
> +		case 5400:
> +			val = BIT_RATE_HBR2;
> +			break;
> +		case 8100:
> +			val = BIT_RATE_HBR3;
> +			break;
> +		}
> +		regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> +	}
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> +			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> +
> +	return 0;
> +}
> +
> +static int mtk_dp_phy_reset(struct phy *phy)
> +{
> +	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> +
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 0);
> +	usleep_range(50, 200);
> +	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> +			   DP_GLB_SW_RST_PHYD, 1);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_dp_phy_dev_ops = {
> +	.init = mtk_dp_phy_init,
> +	.configure = mtk_dp_phy_configure,
> +	.reset = mtk_dp_phy_reset,
> +	.owner = THIS_MODULE,
> +};
> +
> +static int mtk_dp_phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_dp_phy *dp_phy;
> +	struct phy *phy;
> +	struct regmap *regs;
> +
> +	regs = *(struct regmap **)dev->platform_data;
> +	if (!regs)
> +		return dev_err_probe(dev, EINVAL, "No data passed, requires struct regmap**\n");
> +
> +	dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> +	if (!dp_phy)
> +		return -ENOMEM;
> +
> +	dp_phy->regs = regs;
> +	phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create DP PHY\n");
> +
> +	phy_set_drvdata(phy, dp_phy);
> +	if (!dev->of_node)
> +		phy_create_lookup(phy, "dp", dev_name(dev));
> +
> +	return 0;
> +}
> +
> +struct platform_driver mtk_dp_phy_driver = {
> +	.probe = mtk_dp_phy_probe,
> +	.driver = {
> +		.name = "mediatek-dp-phy",
> +	},
> +};
> +module_platform_driver(mtk_dp_phy_driver);
> +
> +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.35.1

-- 
~Vinod

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-08 10:26       ` Rex-BC Chen
                           ` (2 preceding siblings ...)
  (?)
@ 2022-06-09  2:30         ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  2:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > +{
> > > +	ssize_t ret;
> > > +	u8 sink_count;
> > > +	bool locked;
> > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > +
> > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > &sink_count);
> > > +	if (ret < 0) {
> > > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > > %ld\n", ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > link_status,
> > > +			       sizeof(link_status));
> > > +	if (!ret) {
> > > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > > %ld\n",
> > > +			ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > +				      mtk_dp->train_info.lane_count);
> > > +	if (!locked && mtk_dp->train_state >
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > 
> > Before enter this function, mtk_dp->train_state is set to
> > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > 
> 
> The interrupt from sink device could come any time. Why it's
> impossible?

I still ask this question: "For eDP, when does disconnect happened?" If
it indeed happen, I still do not like to change state here. When
disconnect, the training flow would result in fail finally and need not
to change state here, but the training flow would block for a while
when disconnect. You could add some check point to check train_info-
>cable_plugged_in to quickly break out the training flow.

Regards,
CK

> 
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > +
> > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > > +
> > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > +		mtk_dp->train_info.check_cap_count = 0;
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> > 
> > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > mtk_dp_parse_capabilities() is true then change to
> > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > different.
> > 
> > Regards,
> > CK
> > 
> 
> I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> We can check enable status in another place.
> 
> BRs,
> Bo-Chen
> 
> > > +		msleep(20);
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  2:30         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  2:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > +{
> > > +	ssize_t ret;
> > > +	u8 sink_count;
> > > +	bool locked;
> > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > +
> > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > &sink_count);
> > > +	if (ret < 0) {
> > > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > > %ld\n", ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > link_status,
> > > +			       sizeof(link_status));
> > > +	if (!ret) {
> > > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > > %ld\n",
> > > +			ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > +				      mtk_dp->train_info.lane_count);
> > > +	if (!locked && mtk_dp->train_state >
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > 
> > Before enter this function, mtk_dp->train_state is set to
> > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > 
> 
> The interrupt from sink device could come any time. Why it's
> impossible?

I still ask this question: "For eDP, when does disconnect happened?" If
it indeed happen, I still do not like to change state here. When
disconnect, the training flow would result in fail finally and need not
to change state here, but the training flow would block for a while
when disconnect. You could add some check point to check train_info-
>cable_plugged_in to quickly break out the training flow.

Regards,
CK

> 
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > +
> > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > > +
> > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > +		mtk_dp->train_info.check_cap_count = 0;
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> > 
> > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > mtk_dp_parse_capabilities() is true then change to
> > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > different.
> > 
> > Regards,
> > CK
> > 
> 
> I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> We can check enable status in another place.
> 
> BRs,
> Bo-Chen
> 
> > > +		msleep(20);
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > 
> > 
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  2:30         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  2:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > +{
> > > +	ssize_t ret;
> > > +	u8 sink_count;
> > > +	bool locked;
> > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > +
> > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > &sink_count);
> > > +	if (ret < 0) {
> > > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > > %ld\n", ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > link_status,
> > > +			       sizeof(link_status));
> > > +	if (!ret) {
> > > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > > %ld\n",
> > > +			ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > +				      mtk_dp->train_info.lane_count);
> > > +	if (!locked && mtk_dp->train_state >
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > 
> > Before enter this function, mtk_dp->train_state is set to
> > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > 
> 
> The interrupt from sink device could come any time. Why it's
> impossible?

I still ask this question: "For eDP, when does disconnect happened?" If
it indeed happen, I still do not like to change state here. When
disconnect, the training flow would result in fail finally and need not
to change state here, but the training flow would block for a while
when disconnect. You could add some check point to check train_info-
>cable_plugged_in to quickly break out the training flow.

Regards,
CK

> 
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > +
> > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > > +
> > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > +		mtk_dp->train_info.check_cap_count = 0;
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> > 
> > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > mtk_dp_parse_capabilities() is true then change to
> > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > different.
> > 
> > Regards,
> > CK
> > 
> 
> I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> We can check enable status in another place.
> 
> BRs,
> Bo-Chen
> 
> > > +		msleep(20);
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  2:30         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  2:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > +{
> > > +	ssize_t ret;
> > > +	u8 sink_count;
> > > +	bool locked;
> > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > +
> > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > &sink_count);
> > > +	if (ret < 0) {
> > > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > > %ld\n", ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > link_status,
> > > +			       sizeof(link_status));
> > > +	if (!ret) {
> > > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > > %ld\n",
> > > +			ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > +				      mtk_dp->train_info.lane_count);
> > > +	if (!locked && mtk_dp->train_state >
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > 
> > Before enter this function, mtk_dp->train_state is set to
> > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > 
> 
> The interrupt from sink device could come any time. Why it's
> impossible?

I still ask this question: "For eDP, when does disconnect happened?" If
it indeed happen, I still do not like to change state here. When
disconnect, the training flow would result in fail finally and need not
to change state here, but the training flow would block for a while
when disconnect. You could add some check point to check train_info-
>cable_plugged_in to quickly break out the training flow.

Regards,
CK

> 
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > +
> > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > > +
> > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > +		mtk_dp->train_info.check_cap_count = 0;
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> > 
> > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > mtk_dp_parse_capabilities() is true then change to
> > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > different.
> > 
> > Regards,
> > CK
> > 
> 
> I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> We can check enable status in another place.
> 
> BRs,
> Bo-Chen
> 
> > > +		msleep(20);
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > 
> > 
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  2:30         ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  2:30 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > Hi, Rex:
> > 
> > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > 
> > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > 
> > > It supports the mt8195, the embedded DisplayPort units. It offers
> > > 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 <jason-jh.lin@mediatek.com>.
> > > 
> > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > ---
> > 
> > [snip]
> > 
> > > +
> > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > +{
> > > +	ssize_t ret;
> > > +	u8 sink_count;
> > > +	bool locked;
> > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > +
> > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > &sink_count);
> > > +	if (ret < 0) {
> > > +		drm_err(mtk_dp->drm_dev, "Read sink count failed:
> > > %ld\n", ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > link_status,
> > > +			       sizeof(link_status));
> > > +	if (!ret) {
> > > +		drm_err(mtk_dp->drm_dev, "Read link status failed:
> > > %ld\n",
> > > +			ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > +				      mtk_dp->train_info.lane_count);
> > > +	if (!locked && mtk_dp->train_state >
> > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > 
> > Before enter this function, mtk_dp->train_state is set to
> > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > 
> 
> The interrupt from sink device could come any time. Why it's
> impossible?

I still ask this question: "For eDP, when does disconnect happened?" If
it indeed happen, I still do not like to change state here. When
disconnect, the training flow would result in fail finally and need not
to change state here, but the training flow would block for a while
when disconnect. You could add some check point to check train_info-
>cable_plugged_in to quickly break out the training flow.

Regards,
CK

> 
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > +
> > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > +				   DP_REMOTE_CONTROL_COMMAND_PENDING);
> > > +
> > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > +	    (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > +		mtk_dp->train_info.check_cap_count = 0;
> > > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKEDID;
> > 
> > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > mtk_dp_parse_capabilities() is true then change to
> > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > different.
> > 
> > Regards,
> > CK
> > 
> 
> I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> We can check enable status in another place.
> 
> BRs,
> Bo-Chen
> 
> > > +		msleep(20);
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07  8:01     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-09  7:18       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:18 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 16:01 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	switch (mtk_dp->state) {
> 
> Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
> mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
> calling mtk_dp_state_handler() out of mtk_dp_train_handler().
> 
> Regards,
> CK
> 

Hello CK,

OK, I will refine this flow.
About the state machine of traning flow, we can review in v11.

BRs,
Bo-Chen

> > +	case MTK_DP_STATE_INITIAL:
> > +		mtk_dp_video_mute(mtk_dp, true);
> > +		mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_IDLE:
> > +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> > +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_PREPARE:
> > +		mtk_dp_video_config(mtk_dp);
> > +		mtk_dp_video_enable(mtk_dp, true);
> > +
> > +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> > +		break;
> > +
> > +	case MTK_DP_STATE_NORMAL:
> > +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> > +			mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		}
> > +		break;
> > +
> > +	default:
> > +		break;
> > +	}
> > +}
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  7:18       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:18 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Tue, 2022-06-07 at 16:01 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	switch (mtk_dp->state) {
> 
> Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
> mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
> calling mtk_dp_state_handler() out of mtk_dp_train_handler().
> 
> Regards,
> CK
> 

Hello CK,

OK, I will refine this flow.
About the state machine of traning flow, we can review in v11.

BRs,
Bo-Chen

> > +	case MTK_DP_STATE_INITIAL:
> > +		mtk_dp_video_mute(mtk_dp, true);
> > +		mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_IDLE:
> > +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> > +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_PREPARE:
> > +		mtk_dp_video_config(mtk_dp);
> > +		mtk_dp_video_enable(mtk_dp, true);
> > +
> > +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> > +		break;
> > +
> > +	case MTK_DP_STATE_NORMAL:
> > +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> > +			mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		}
> > +		break;
> > +
> > +	default:
> > +		break;
> > +	}
> > +}
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  7:18       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:18 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 16:01 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	switch (mtk_dp->state) {
> 
> Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
> mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
> calling mtk_dp_state_handler() out of mtk_dp_train_handler().
> 
> Regards,
> CK
> 

Hello CK,

OK, I will refine this flow.
About the state machine of traning flow, we can review in v11.

BRs,
Bo-Chen

> > +	case MTK_DP_STATE_INITIAL:
> > +		mtk_dp_video_mute(mtk_dp, true);
> > +		mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_IDLE:
> > +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> > +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_PREPARE:
> > +		mtk_dp_video_config(mtk_dp);
> > +		mtk_dp_video_enable(mtk_dp, true);
> > +
> > +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> > +		break;
> > +
> > +	case MTK_DP_STATE_NORMAL:
> > +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> > +			mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		}
> > +		break;
> > +
> > +	default:
> > +		break;
> > +	}
> > +}
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  7:18       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:18 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 16:01 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	switch (mtk_dp->state) {
> 
> Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
> mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
> calling mtk_dp_state_handler() out of mtk_dp_train_handler().
> 
> Regards,
> CK
> 

Hello CK,

OK, I will refine this flow.
About the state machine of traning flow, we can review in v11.

BRs,
Bo-Chen

> > +	case MTK_DP_STATE_INITIAL:
> > +		mtk_dp_video_mute(mtk_dp, true);
> > +		mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_IDLE:
> > +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> > +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_PREPARE:
> > +		mtk_dp_video_config(mtk_dp);
> > +		mtk_dp_video_enable(mtk_dp, true);
> > +
> > +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> > +		break;
> > +
> > +	case MTK_DP_STATE_NORMAL:
> > +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> > +			mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		}
> > +		break;
> > +
> > +	default:
> > +		break;
> > +	}
> > +}
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  7:18       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:18 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 16:01 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static void mtk_dp_state_handler(struct mtk_dp *mtk_dp)
> > +{
> > +	switch (mtk_dp->state) {
> 
> Does mtk_dp->state has any relation with mtk_dp->train_state. If yes,
> mix mtk_dp->state and mtk_dp->train_state into one state. If no, move
> calling mtk_dp_state_handler() out of mtk_dp_train_handler().
> 
> Regards,
> CK
> 

Hello CK,

OK, I will refine this flow.
About the state machine of traning flow, we can review in v11.

BRs,
Bo-Chen

> > +	case MTK_DP_STATE_INITIAL:
> > +		mtk_dp_video_mute(mtk_dp, true);
> > +		mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_IDLE:
> > +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> > +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> > +		break;
> > +
> > +	case MTK_DP_STATE_PREPARE:
> > +		mtk_dp_video_config(mtk_dp);
> > +		mtk_dp_video_enable(mtk_dp, true);
> > +
> > +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> > +		break;
> > +
> > +	case MTK_DP_STATE_NORMAL:
> > +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> > +			mtk_dp->state = MTK_DP_STATE_IDLE;
> > +		}
> > +		break;
> > +
> > +	default:
> > +		break;
> > +	}
> > +}
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-09  2:30         ` CK Hu
                             ` (2 preceding siblings ...)
  (?)
@ 2022-06-09  7:24           ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-09 at 10:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	ssize_t ret;
> > > > +	u8 sink_count;
> > > > +	bool locked;
> > > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > > +
> > > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > > &sink_count);
> > > > +	if (ret < 0) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read sink count
> > > > failed:
> > > > %ld\n", ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > > link_status,
> > > > +			       sizeof(link_status));
> > > > +	if (!ret) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read link status
> > > > failed:
> > > > %ld\n",
> > > > +			ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > > +				      mtk_dp-
> > > > >train_info.lane_count);
> > > > +	if (!locked && mtk_dp->train_state >
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > > 
> > > Before enter this function, mtk_dp->train_state is set to
> > > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > > 
> > 
> > The interrupt from sink device could come any time. Why it's
> > impossible?
> 
> I still ask this question: "For eDP, when does disconnect happened?"
> If
> it indeed happen, I still do not like to change state here. When
> disconnect, the training flow would result in fail finally and need
> not
> to change state here, but the training flow would block for a while
> when disconnect. You could add some check point to check train_info-
> > cable_plugged_in to quickly break out the training flow.
> 
> Regards,
> CK
> 

Hello CK,

This function is to handle "sink interrupt" and we need to read the
status from sink device via aux channel.
edp spec is just add some extension rule from dp spec, this is define
in dp spec.

The basic spec is still "dp", and these are all define in dp spec.
Therefore, I think we should keep this.

BRs,
Bo-Chen

> > 
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > > +
> > > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > > +				   DP_REMOTE_CONTROL_COMMAND_PE
> > > > NDING);
> > > > +
> > > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > > +	    (link_status[2] &
> > > > DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > > +		mtk_dp->train_info.check_cap_count = 0;
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > 
> > > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > > mtk_dp_parse_capabilities() is true then change to
> > > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > > different.
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> > MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> > We can check enable status in another place.
> > 
> > BRs,
> > Bo-Chen
> > 
> > > > +		msleep(20);
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  7:24           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Thu, 2022-06-09 at 10:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	ssize_t ret;
> > > > +	u8 sink_count;
> > > > +	bool locked;
> > > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > > +
> > > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > > &sink_count);
> > > > +	if (ret < 0) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read sink count
> > > > failed:
> > > > %ld\n", ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > > link_status,
> > > > +			       sizeof(link_status));
> > > > +	if (!ret) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read link status
> > > > failed:
> > > > %ld\n",
> > > > +			ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > > +				      mtk_dp-
> > > > >train_info.lane_count);
> > > > +	if (!locked && mtk_dp->train_state >
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > > 
> > > Before enter this function, mtk_dp->train_state is set to
> > > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > > 
> > 
> > The interrupt from sink device could come any time. Why it's
> > impossible?
> 
> I still ask this question: "For eDP, when does disconnect happened?"
> If
> it indeed happen, I still do not like to change state here. When
> disconnect, the training flow would result in fail finally and need
> not
> to change state here, but the training flow would block for a while
> when disconnect. You could add some check point to check train_info-
> > cable_plugged_in to quickly break out the training flow.
> 
> Regards,
> CK
> 

Hello CK,

This function is to handle "sink interrupt" and we need to read the
status from sink device via aux channel.
edp spec is just add some extension rule from dp spec, this is define
in dp spec.

The basic spec is still "dp", and these are all define in dp spec.
Therefore, I think we should keep this.

BRs,
Bo-Chen

> > 
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > > +
> > > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > > +				   DP_REMOTE_CONTROL_COMMAND_PE
> > > > NDING);
> > > > +
> > > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > > +	    (link_status[2] &
> > > > DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > > +		mtk_dp->train_info.check_cap_count = 0;
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > 
> > > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > > mtk_dp_parse_capabilities() is true then change to
> > > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > > different.
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> > MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> > We can check enable status in another place.
> > 
> > BRs,
> > Bo-Chen
> > 
> > > > +		msleep(20);
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  7:24           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-09 at 10:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	ssize_t ret;
> > > > +	u8 sink_count;
> > > > +	bool locked;
> > > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > > +
> > > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > > &sink_count);
> > > > +	if (ret < 0) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read sink count
> > > > failed:
> > > > %ld\n", ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > > link_status,
> > > > +			       sizeof(link_status));
> > > > +	if (!ret) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read link status
> > > > failed:
> > > > %ld\n",
> > > > +			ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > > +				      mtk_dp-
> > > > >train_info.lane_count);
> > > > +	if (!locked && mtk_dp->train_state >
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > > 
> > > Before enter this function, mtk_dp->train_state is set to
> > > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > > 
> > 
> > The interrupt from sink device could come any time. Why it's
> > impossible?
> 
> I still ask this question: "For eDP, when does disconnect happened?"
> If
> it indeed happen, I still do not like to change state here. When
> disconnect, the training flow would result in fail finally and need
> not
> to change state here, but the training flow would block for a while
> when disconnect. You could add some check point to check train_info-
> > cable_plugged_in to quickly break out the training flow.
> 
> Regards,
> CK
> 

Hello CK,

This function is to handle "sink interrupt" and we need to read the
status from sink device via aux channel.
edp spec is just add some extension rule from dp spec, this is define
in dp spec.

The basic spec is still "dp", and these are all define in dp spec.
Therefore, I think we should keep this.

BRs,
Bo-Chen

> > 
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > > +
> > > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > > +				   DP_REMOTE_CONTROL_COMMAND_PE
> > > > NDING);
> > > > +
> > > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > > +	    (link_status[2] &
> > > > DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > > +		mtk_dp->train_info.check_cap_count = 0;
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > 
> > > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > > mtk_dp_parse_capabilities() is true then change to
> > > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > > different.
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> > MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> > We can check enable status in another place.
> > 
> > BRs,
> > Bo-Chen
> > 
> > > > +		msleep(20);
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  7:24           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-09 at 10:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	ssize_t ret;
> > > > +	u8 sink_count;
> > > > +	bool locked;
> > > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > > +
> > > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > > &sink_count);
> > > > +	if (ret < 0) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read sink count
> > > > failed:
> > > > %ld\n", ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > > link_status,
> > > > +			       sizeof(link_status));
> > > > +	if (!ret) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read link status
> > > > failed:
> > > > %ld\n",
> > > > +			ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > > +				      mtk_dp-
> > > > >train_info.lane_count);
> > > > +	if (!locked && mtk_dp->train_state >
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > > 
> > > Before enter this function, mtk_dp->train_state is set to
> > > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > > 
> > 
> > The interrupt from sink device could come any time. Why it's
> > impossible?
> 
> I still ask this question: "For eDP, when does disconnect happened?"
> If
> it indeed happen, I still do not like to change state here. When
> disconnect, the training flow would result in fail finally and need
> not
> to change state here, but the training flow would block for a while
> when disconnect. You could add some check point to check train_info-
> > cable_plugged_in to quickly break out the training flow.
> 
> Regards,
> CK
> 

Hello CK,

This function is to handle "sink interrupt" and we need to read the
status from sink device via aux channel.
edp spec is just add some extension rule from dp spec, this is define
in dp spec.

The basic spec is still "dp", and these are all define in dp spec.
Therefore, I think we should keep this.

BRs,
Bo-Chen

> > 
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > > +
> > > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > > +				   DP_REMOTE_CONTROL_COMMAND_PE
> > > > NDING);
> > > > +
> > > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > > +	    (link_status[2] &
> > > > DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > > +		mtk_dp->train_info.check_cap_count = 0;
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > 
> > > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > > mtk_dp_parse_capabilities() is true then change to
> > > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > > different.
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> > MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> > We can check enable status in another place.
> > 
> > BRs,
> > Bo-Chen
> > 
> > > > +		msleep(20);
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  7:24           ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  7:24 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-09 at 10:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Wed, 2022-06-08 at 18:26 +0800, Rex-BC Chen wrote:
> > On Tue, 2022-06-07 at 15:47 +0800, CK Hu wrote:
> > > Hi, Rex:
> > > 
> > > On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > > > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > 
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195
> > > > SoC.
> > > > 
> > > > It supports the mt8195, the embedded DisplayPort units. It
> > > > offers
> > > > 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 <jason-jh.lin@mediatek.com>.
> > > > 
> > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > > > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +
> > > > +static int mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > > > +{
> > > > +	ssize_t ret;
> > > > +	u8 sink_count;
> > > > +	bool locked;
> > > > +	u8 link_status[DP_LINK_STATUS_SIZE] = {};
> > > > +	u32 sink_count_reg = DP_SINK_COUNT_ESI;
> > > > +	u32 link_status_reg = DP_LANE0_1_STATUS;
> > > > +
> > > > +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, sink_count_reg,
> > > > &sink_count);
> > > > +	if (ret < 0) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read sink count
> > > > failed:
> > > > %ld\n", ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	ret = drm_dp_dpcd_read(&mtk_dp->aux, link_status_reg,
> > > > link_status,
> > > > +			       sizeof(link_status));
> > > > +	if (!ret) {
> > > > +		drm_err(mtk_dp->drm_dev, "Read link status
> > > > failed:
> > > > %ld\n",
> > > > +			ret);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	locked = drm_dp_channel_eq_ok(link_status,
> > > > +				      mtk_dp-
> > > > >train_info.lane_count);
> > > > +	if (!locked && mtk_dp->train_state >
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE)
> > > 
> > > Before enter this function, mtk_dp->train_state is set to
> > > MTK_DP_TRAIN_STATE_STARTUP, so this never happen, drop this.
> > > 
> > 
> > The interrupt from sink device could come any time. Why it's
> > impossible?
> 
> I still ask this question: "For eDP, when does disconnect happened?"
> If
> it indeed happen, I still do not like to change state here. When
> disconnect, the training flow would result in fail finally and need
> not
> to change state here, but the training flow would block for a while
> when disconnect. You could add some check point to check train_info-
> > cable_plugged_in to quickly break out the training flow.
> 
> Regards,
> CK
> 

Hello CK,

This function is to handle "sink interrupt" and we need to read the
status from sink device via aux channel.
edp spec is just add some extension rule from dp spec, this is define
in dp spec.

The basic spec is still "dp", and these are all define in dp spec.
Therefore, I think we should keep this.

BRs,
Bo-Chen

> > 
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_TRAINING_PRE;
> > > > +
> > > > +	if (link_status[1] & DP_REMOTE_CONTROL_COMMAND_PENDING)
> > > > +		drm_dp_dpcd_writeb(&mtk_dp->aux,
> > > > DP_DEVICE_SERVICE_IRQ_VECTOR,
> > > > +				   DP_REMOTE_CONTROL_COMMAND_PE
> > > > NDING);
> > > > +
> > > > +	if (DP_GET_SINK_COUNT(sink_count) &&
> > > > +	    (link_status[2] &
> > > > DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > > > +		mtk_dp->train_info.check_cap_count = 0;
> > > > +		mtk_dp->train_state =
> > > > MTK_DP_TRAIN_STATE_CHECKEDID;
> > > 
> > > Why change state from MTK_DP_TRAIN_STATE_STARTUP to
> > > MTK_DP_TRAIN_STATE_CHECKEDID? In mtk_dp_train_handler(),
> > > mtk_dp_parse_capabilities() is true then change to
> > > MTK_DP_TRAIN_STATE_CHECKEDID. Give a reason why these two are
> > > different.
> > > 
> > > Regards,
> > > CK
> > > 
> > 
> > I will drop this and drop state of MTK_DP_TRAIN_STATE_CHECKEDID.
> > MTK_DP_TRAIN_STATE_CHECKEDID is only used for audio.
> > We can check enable status in another place.
> > 
> > BRs,
> > Bo-Chen
> > 
> > > > +		msleep(20);
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > 
> > > 
> > 
> > 
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-07  9:04     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-09  8:00       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:00 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 17:04 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> 
> For eDP, when does 'unplug' happen? Explain this or move unplug
> processing to DP patch.
> 
> Regards,
> CK
> 

Hello CK,

ok, I move them to dp patch.

BRs,
Bo-Chen

> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  8:00       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:00 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 17:04 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> 
> For eDP, when does 'unplug' happen? Explain this or move unplug
> processing to DP patch.
> 
> Regards,
> CK
> 

Hello CK,

ok, I move them to dp patch.

BRs,
Bo-Chen

> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  8:00       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:00 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Tue, 2022-06-07 at 17:04 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> 
> For eDP, when does 'unplug' happen? Explain this or move unplug
> processing to DP patch.
> 
> Regards,
> CK
> 

Hello CK,

ok, I move them to dp patch.

BRs,
Bo-Chen

> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  8:00       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:00 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 17:04 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> 
> For eDP, when does 'unplug' happen? Explain this or move unplug
> processing to DP patch.
> 
> Regards,
> CK
> 

Hello CK,

ok, I move them to dp patch.

BRs,
Bo-Chen

> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  8:00       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:00 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-06-07 at 17:04 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> > +{
> > +	struct mtk_dp *mtk_dp = dev;
> > +	int event;
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +
> > +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> > :
> > +						  connector_status_disc
> > onnected;
> > +
> > +	if (event < 0)
> > +		return IRQ_HANDLED;
> > +
> > +	if (mtk_dp->drm_dev) {
> > +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> > +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> > +	}
> > +
> > +	if (mtk_dp->train_info.cable_state_change) {
> > +		mtk_dp->train_info.cable_state_change = false;
> > +
> > +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> > +
> > +		if (!mtk_dp->train_info.cable_plugged_in ||
> > +		    !mtk_dp_plug_state(mtk_dp)) {
> > +			mtk_dp_video_mute(mtk_dp, true);
> 
> For eDP, when does 'unplug' happen? Explain this or move unplug
> processing to DP patch.
> 
> Regards,
> CK
> 

Hello CK,

ok, I move them to dp patch.

BRs,
Bo-Chen

> > +
> > +			mtk_dp_initialize_priv_data(mtk_dp);
> > +			mtk_dp_set_idle_pattern(mtk_dp, true);
> > +			if (mtk_dp->has_fec)
> > +				mtk_dp_fec_enable(mtk_dp, false);
> > +
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL,
> > +					   DP_PWR_STATE_MASK);
> > +		} else {
> > +			mtk_dp_update_bits(mtk_dp,
> > MTK_DP_TOP_PWR_STATE,
> > +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> > NE,
> > +					   DP_PWR_STATE_MASK);
> > +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +			mtk_dp->train_info.link_rate =
> > +				min_t(int, mtk_dp->max_linkrate,
> > +				      buf[mtk_dp->max_linkrate]);
> > +			mtk_dp->train_info.lane_count =
> > +				min_t(int, mtk_dp->max_lanes,
> > +				      drm_dp_max_lane_count(buf));
> > +		}
> > +	}
> > +
> > +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> > +		dev_dbg(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> > +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> > +		mtk_dp_hpd_sink_event(mtk_dp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-08  8:30     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-09  8:03       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:03 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 16:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> > +{
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +	u8 val;
> > +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> > +
> > +	if (!mtk_dp_plug_state(mtk_dp))
> > +		return false;
> > +
> > +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0);
> > +	/* Wait for power on */
> > +	usleep_range(2000, 5000);
> > +
> > +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +
> > +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> > sizeof(buf)));
> 
> sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so
> 
> drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);
> 
> 

Hello CK,

I will drop buf[].

> > +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> > DP_TRAINING_AUX_RD_MASK;
> > +
> > +	train_info->link_rate =
> > +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> > > max_linkrate]);
> > 
> > +	train_info->lane_count =
> > +		min_t(int, mtk_dp->max_lanes,
> > drm_dp_max_lane_count(buf));
> > +
> > +	train_info->tps3 = drm_dp_tps3_supported(buf);
> > +	train_info->tps4 = drm_dp_tps4_supported(buf);
> > +
> > +	train_info->sink_ssc =
> > +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> > +
> > +	train_info->sink_ssc = false;
> 
> What does these two statement do?
> 

ssc = Spread spectrum clock.
it's for both edp and dp.

BRs,
Bo-Chen

> Regards,
> CK
> 
> > +
> > +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> > +	if (val & DP_MST_CAP) {
> > +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> > +		drm_dp_dpcd_readb(&mtk_dp->aux,
> > +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> > &val);
> > +		if (val)
> > +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> > +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> > _ESI0,
> > +					   val);
> > +	}
> > +
> > +	return true;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  8:03       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:03 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-06-08 at 16:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> > +{
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +	u8 val;
> > +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> > +
> > +	if (!mtk_dp_plug_state(mtk_dp))
> > +		return false;
> > +
> > +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0);
> > +	/* Wait for power on */
> > +	usleep_range(2000, 5000);
> > +
> > +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +
> > +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> > sizeof(buf)));
> 
> sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so
> 
> drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);
> 
> 

Hello CK,

I will drop buf[].

> > +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> > DP_TRAINING_AUX_RD_MASK;
> > +
> > +	train_info->link_rate =
> > +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> > > max_linkrate]);
> > 
> > +	train_info->lane_count =
> > +		min_t(int, mtk_dp->max_lanes,
> > drm_dp_max_lane_count(buf));
> > +
> > +	train_info->tps3 = drm_dp_tps3_supported(buf);
> > +	train_info->tps4 = drm_dp_tps4_supported(buf);
> > +
> > +	train_info->sink_ssc =
> > +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> > +
> > +	train_info->sink_ssc = false;
> 
> What does these two statement do?
> 

ssc = Spread spectrum clock.
it's for both edp and dp.

BRs,
Bo-Chen

> Regards,
> CK
> 
> > +
> > +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> > +	if (val & DP_MST_CAP) {
> > +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> > +		drm_dp_dpcd_readb(&mtk_dp->aux,
> > +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> > &val);
> > +		if (val)
> > +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> > +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> > _ESI0,
> > +					   val);
> > +	}
> > +
> > +	return true;
> > +}
> > +
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  8:03       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:03 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 16:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> > +{
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +	u8 val;
> > +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> > +
> > +	if (!mtk_dp_plug_state(mtk_dp))
> > +		return false;
> > +
> > +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0);
> > +	/* Wait for power on */
> > +	usleep_range(2000, 5000);
> > +
> > +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +
> > +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> > sizeof(buf)));
> 
> sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so
> 
> drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);
> 
> 

Hello CK,

I will drop buf[].

> > +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> > DP_TRAINING_AUX_RD_MASK;
> > +
> > +	train_info->link_rate =
> > +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> > > max_linkrate]);
> > 
> > +	train_info->lane_count =
> > +		min_t(int, mtk_dp->max_lanes,
> > drm_dp_max_lane_count(buf));
> > +
> > +	train_info->tps3 = drm_dp_tps3_supported(buf);
> > +	train_info->tps4 = drm_dp_tps4_supported(buf);
> > +
> > +	train_info->sink_ssc =
> > +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> > +
> > +	train_info->sink_ssc = false;
> 
> What does these two statement do?
> 

ssc = Spread spectrum clock.
it's for both edp and dp.

BRs,
Bo-Chen

> Regards,
> CK
> 
> > +
> > +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> > +	if (val & DP_MST_CAP) {
> > +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> > +		drm_dp_dpcd_readb(&mtk_dp->aux,
> > +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> > &val);
> > +		if (val)
> > +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> > +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> > _ESI0,
> > +					   val);
> > +	}
> > +
> > +	return true;
> > +}
> > +
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  8:03       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:03 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 16:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> > +{
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +	u8 val;
> > +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> > +
> > +	if (!mtk_dp_plug_state(mtk_dp))
> > +		return false;
> > +
> > +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0);
> > +	/* Wait for power on */
> > +	usleep_range(2000, 5000);
> > +
> > +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +
> > +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> > sizeof(buf)));
> 
> sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so
> 
> drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);
> 
> 

Hello CK,

I will drop buf[].

> > +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> > DP_TRAINING_AUX_RD_MASK;
> > +
> > +	train_info->link_rate =
> > +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> > > max_linkrate]);
> > 
> > +	train_info->lane_count =
> > +		min_t(int, mtk_dp->max_lanes,
> > drm_dp_max_lane_count(buf));
> > +
> > +	train_info->tps3 = drm_dp_tps3_supported(buf);
> > +	train_info->tps4 = drm_dp_tps4_supported(buf);
> > +
> > +	train_info->sink_ssc =
> > +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> > +
> > +	train_info->sink_ssc = false;
> 
> What does these two statement do?
> 

ssc = Spread spectrum clock.
it's for both edp and dp.

BRs,
Bo-Chen

> Regards,
> CK
> 
> > +
> > +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> > +	if (val & DP_MST_CAP) {
> > +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> > +		drm_dp_dpcd_readb(&mtk_dp->aux,
> > +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> > &val);
> > +		if (val)
> > +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> > +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> > _ESI0,
> > +					   val);
> > +	}
> > +
> > +	return true;
> > +}
> > +
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  8:03       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-09  8:03 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-06-08 at 16:30 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static bool mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
> > +{
> > +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> > +	u8 val;
> > +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> > +
> > +	if (!mtk_dp_plug_state(mtk_dp))
> > +		return false;
> > +
> > +	drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0);
> > +	/* Wait for power on */
> > +	usleep_range(2000, 5000);
> > +
> > +	drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> > +
> > +	memcpy(mtk_dp->rx_cap, buf, min(sizeof(mtk_dp->rx_cap),
> > sizeof(buf)));
> 
> sizeof(mtk_dp->rx_cap) is identical to sizeof(buf), so
> 
> drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);
> 
> 

Hello CK,

I will drop buf[].

> > +	mtk_dp->rx_cap[DP_TRAINING_AUX_RD_INTERVAL] &=
> > DP_TRAINING_AUX_RD_MASK;
> > +
> > +	train_info->link_rate =
> > +		min_t(int, mtk_dp->max_linkrate, buf[mtk_dp-
> > > max_linkrate]);
> > 
> > +	train_info->lane_count =
> > +		min_t(int, mtk_dp->max_lanes,
> > drm_dp_max_lane_count(buf));
> > +
> > +	train_info->tps3 = drm_dp_tps3_supported(buf);
> > +	train_info->tps4 = drm_dp_tps4_supported(buf);
> > +
> > +	train_info->sink_ssc =
> > +		!!(buf[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
> > +
> > +	train_info->sink_ssc = false;
> 
> What does these two statement do?
> 

ssc = Spread spectrum clock.
it's for both edp and dp.

BRs,
Bo-Chen

> Regards,
> CK
> 
> > +
> > +	drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
> > +	if (val & DP_MST_CAP) {
> > +		/* Clear DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 */
> > +		drm_dp_dpcd_readb(&mtk_dp->aux,
> > +				  DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
> > &val);
> > +		if (val)
> > +			drm_dp_dpcd_writeb(&mtk_dp->aux,
> > +					   DP_DEVICE_SERVICE_IRQ_VECTOR
> > _ESI0,
> > +					   val);
> > +	}
> > +
> > +	return true;
> > +}
> > +
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-05-23 10:47   ` Guillaume Ranquet
                       ` (2 preceding siblings ...)
  (?)
@ 2022-06-09  9:37     ` CK Hu
  -1 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  9:37 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> +{
> +	int ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,

MTK_DP_0034 is defined as:

+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))

I think this a weird address.

> +			   DA_CKM_CKTX0_EN_FORCE_EN |
> DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> +		     DA_CKM_BIAS_EN_FORCE_VAL |
> +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> +
> +	if (ret)
> +		return ret;
> +
> +	/* Disable RX */
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);


MTK_DP_1040 is defined as:

+#define MTK_DP_1040		      (BIT(6) | BIT(12))

I think this a weird address.

Regards,
CK

> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> BIT(MEM_ISO_EN_SHIFT));
> +
> +	return ret;
> +}


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  9:37     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  9:37 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> +{
> +	int ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,

MTK_DP_0034 is defined as:

+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))

I think this a weird address.

> +			   DA_CKM_CKTX0_EN_FORCE_EN |
> DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> +		     DA_CKM_BIAS_EN_FORCE_VAL |
> +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> +
> +	if (ret)
> +		return ret;
> +
> +	/* Disable RX */
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);


MTK_DP_1040 is defined as:

+#define MTK_DP_1040		      (BIT(6) | BIT(12))

I think this a weird address.

Regards,
CK

> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> BIT(MEM_ISO_EN_SHIFT));
> +
> +	return ret;
> +}


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  9:37     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  9:37 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> +{
> +	int ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,

MTK_DP_0034 is defined as:

+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))

I think this a weird address.

> +			   DA_CKM_CKTX0_EN_FORCE_EN |
> DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> +		     DA_CKM_BIAS_EN_FORCE_VAL |
> +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> +
> +	if (ret)
> +		return ret;
> +
> +	/* Disable RX */
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);


MTK_DP_1040 is defined as:

+#define MTK_DP_1040		      (BIT(6) | BIT(12))

I think this a weird address.

Regards,
CK

> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> BIT(MEM_ISO_EN_SHIFT));
> +
> +	return ret;
> +}


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  9:37     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  9:37 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> +{
> +	int ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,

MTK_DP_0034 is defined as:

+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))

I think this a weird address.

> +			   DA_CKM_CKTX0_EN_FORCE_EN |
> DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> +		     DA_CKM_BIAS_EN_FORCE_VAL |
> +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> +
> +	if (ret)
> +		return ret;
> +
> +	/* Disable RX */
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);


MTK_DP_1040 is defined as:

+#define MTK_DP_1040		      (BIT(6) | BIT(12))

I think this a weird address.

Regards,
CK

> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> BIT(MEM_ISO_EN_SHIFT));
> +
> +	return ret;
> +}


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-09  9:37     ` CK Hu
  0 siblings, 0 replies; 450+ messages in thread
From: CK Hu @ 2022-06-09  9:37 UTC (permalink / raw)
  To: Rex-BC Chen, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

Hi, Rex:

On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp@baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the embedded DisplayPort units. It offers
> 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 <jason-jh.lin@mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---

[snip]

> +
> +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> +{
> +	int ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,

MTK_DP_0034 is defined as:

+#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))

I think this a weird address.

> +			   DA_CKM_CKTX0_EN_FORCE_EN |
> DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> +		     DA_CKM_BIAS_EN_FORCE_VAL |
> +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> +
> +	if (ret)
> +		return ret;
> +
> +	/* Disable RX */
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);


MTK_DP_1040 is defined as:

+#define MTK_DP_1040		      (BIT(6) | BIT(12))

I think this a weird address.

Regards,
CK

> +
> +	if (ret)
> +		return ret;
> +
> +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> BIT(MEM_ISO_EN_SHIFT));
> +
> +	return ret;
> +}


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
  2022-06-09  9:37     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-10  2:10       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:10 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-09 at 17:37 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
> 
> MTK_DP_0034 is defined as:
> 
> +#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
> 
> I think this a weird address.
> 
> > +			   DA_CKM_CKTX0_EN_FORCE_EN |
> > DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> > +		     DA_CKM_BIAS_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Disable RX */
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
> 
> 
> MTK_DP_1040 is defined as:
> 
> +#define MTK_DP_1040		      (BIT(6) | BIT(12))
> 
> I think this a weird address.
> 
> Regards,
> CK
> 

Hello CK,

I will change them to 0x34 and 0x1040.

BRs,
Rex

> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> > +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> > BIT(MEM_ISO_EN_SHIFT));
> > +
> > +	return ret;
> > +}
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-10  2:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:10 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-09 at 17:37 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
> 
> MTK_DP_0034 is defined as:
> 
> +#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
> 
> I think this a weird address.
> 
> > +			   DA_CKM_CKTX0_EN_FORCE_EN |
> > DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> > +		     DA_CKM_BIAS_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Disable RX */
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
> 
> 
> MTK_DP_1040 is defined as:
> 
> +#define MTK_DP_1040		      (BIT(6) | BIT(12))
> 
> I think this a weird address.
> 
> Regards,
> CK
> 

Hello CK,

I will change them to 0x34 and 0x1040.

BRs,
Rex

> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> > +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> > BIT(MEM_ISO_EN_SHIFT));
> > +
> > +	return ret;
> > +}
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-10  2:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:10 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Thu, 2022-06-09 at 17:37 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
> 
> MTK_DP_0034 is defined as:
> 
> +#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
> 
> I think this a weird address.
> 
> > +			   DA_CKM_CKTX0_EN_FORCE_EN |
> > DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> > +		     DA_CKM_BIAS_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Disable RX */
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
> 
> 
> MTK_DP_1040 is defined as:
> 
> +#define MTK_DP_1040		      (BIT(6) | BIT(12))
> 
> I think this a weird address.
> 
> Regards,
> CK
> 

Hello CK,

I will change them to 0x34 and 0x1040.

BRs,
Rex

> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> > +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> > BIT(MEM_ISO_EN_SHIFT));
> > +
> > +	return ret;
> > +}
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-10  2:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:10 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-09 at 17:37 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
> 
> MTK_DP_0034 is defined as:
> 
> +#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
> 
> I think this a weird address.
> 
> > +			   DA_CKM_CKTX0_EN_FORCE_EN |
> > DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> > +		     DA_CKM_BIAS_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Disable RX */
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
> 
> 
> MTK_DP_1040 is defined as:
> 
> +#define MTK_DP_1040		      (BIT(6) | BIT(12))
> 
> I think this a weird address.
> 
> Regards,
> CK
> 

Hello CK,

I will change them to 0x34 and 0x1040.

BRs,
Rex

> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> > +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> > BIT(MEM_ISO_EN_SHIFT));
> > +
> > +	return ret;
> > +}
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
@ 2022-06-10  2:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:10 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun (云春峰),
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller,
	Jitao Shi (石记涛)
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Thu, 2022-06-09 at 17:37 +0800, CK Hu wrote:
> Hi, Rex:
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static int mtk_dp_power_disable(struct mtk_dp *mtk_dp)
> > +{
> > +	int ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_0034,
> 
> MTK_DP_0034 is defined as:
> 
> +#define MTK_DP_0034		      (BIT(2) | BIT(4) | BIT(5))
> 
> I think this a weird address.
> 
> > +			   DA_CKM_CKTX0_EN_FORCE_EN |
> > DA_CKM_BIAS_LPF_EN_FORCE_VAL |
> > +		     DA_CKM_BIAS_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_LDO_EN_FORCE_VAL |
> > +		     DA_XTP_GLB_AVD10_ON_FORCE_VAL);
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Disable RX */
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_1040, 0);
> 
> 
> MTK_DP_1040 is defined as:
> 
> +#define MTK_DP_1040		      (BIT(6) | BIT(12))
> 
> I think this a weird address.
> 
> Regards,
> CK
> 

Hello CK,

I will change them to 0x34 and 0x1040.

BRs,
Rex

> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mtk_dp_write(mtk_dp, MTK_DP_TOP_MEM_PD,
> > +			   0x550 | BIT(FUSE_SEL_SHIFT) |
> > BIT(MEM_ISO_EN_SHIFT));
> > +
> > +	return ret;
> > +}
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
  2022-05-24  3:35     ` Chunfeng Yun
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-10  2:27       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:27 UTC (permalink / raw)
  To: Chunfeng Yun, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-05-24 at 11:35 +0800, Chunfeng Yun wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >  1 file changed, 99 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> 
> 'edp_tx: ' can be removed
> 

Hello Chunfeng,

ok, I will drop it.

> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> 
> reg = <0x1c500000 0x8000>;
> #address-cells, #size-cells are both 1 by default
> 

I will use "eg = <0x1c500000 0x8000>;" in binding example.

BRs,
Bo-Chen

> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-10  2:27       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:27 UTC (permalink / raw)
  To: Chunfeng Yun, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Tue, 2022-05-24 at 11:35 +0800, Chunfeng Yun wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >  1 file changed, 99 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> 
> 'edp_tx: ' can be removed
> 

Hello Chunfeng,

ok, I will drop it.

> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> 
> reg = <0x1c500000 0x8000>;
> #address-cells, #size-cells are both 1 by default
> 

I will use "eg = <0x1c500000 0x8000>;" in binding example.

BRs,
Bo-Chen

> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-10  2:27       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:27 UTC (permalink / raw)
  To: Chunfeng Yun, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-05-24 at 11:35 +0800, Chunfeng Yun wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >  1 file changed, 99 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> 
> 'edp_tx: ' can be removed
> 

Hello Chunfeng,

ok, I will drop it.

> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> 
> reg = <0x1c500000 0x8000>;
> #address-cells, #size-cells are both 1 by default
> 

I will use "eg = <0x1c500000 0x8000>;" in binding example.

BRs,
Bo-Chen

> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-10  2:27       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:27 UTC (permalink / raw)
  To: Chunfeng Yun, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-05-24 at 11:35 +0800, Chunfeng Yun wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >  1 file changed, 99 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> 
> 'edp_tx: ' can be removed
> 

Hello Chunfeng,

ok, I will drop it.

> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> 
> reg = <0x1c500000 0x8000>;
> #address-cells, #size-cells are both 1 by default
> 

I will use "eg = <0x1c500000 0x8000>;" in binding example.

BRs,
Bo-Chen

> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-10  2:27       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:27 UTC (permalink / raw)
  To: Chunfeng Yun, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Kishon Vijay Abraham I, Vinod Koul,
	Helge Deller, CK Hu, Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Tue, 2022-05-24 at 11:35 +0800, Chunfeng Yun wrote:
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >  .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >  1 file changed, 99 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> 
> 'edp_tx: ' can be removed
> 

Hello Chunfeng,

ok, I will drop it.

> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> 
> reg = <0x1c500000 0x8000>;
> #address-cells, #size-cells are both 1 by default
> 

I will use "eg = <0x1c500000 0x8000>;" in binding example.

BRs,
Bo-Chen

> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
  2022-05-25 15:30     ` AngeloGioacchino Del Regno
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-10  2:29       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:29 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 17:30 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >   1 file changed, 99 insertions(+)
> >   create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> 
> You should add port@0 (and port@1, probably) as required... with what
> you've done
> here, you're saying that "ports" is required, but you're allowing it
> to be empty..
> 
>    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:
>        - port@0
>        - port@1
> 
> ^^^ that's how it should look.
> 

Hello Angelo,

ok, I will add this.

> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> 
> As you've put it (in the example below), the max-linkrate property
> wants a value
> that corresponds to what you find in the HW registers... this is
> wrong.
> 
> Devicetree bindings should be generic and devicetrees shouldn't have
> hardware
> specific bits inside, hence, please change this property to accept a
> link rate
> specified in Mbps and also specify that in the description.
> 
> Thanks,
> Angelo
> 

ok, I will change it to real linkrate value.

BRs,
Bo-Chen

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-10  2:29       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:29 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-05-25 at 17:30 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >   1 file changed, 99 insertions(+)
> >   create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> 
> You should add port@0 (and port@1, probably) as required... with what
> you've done
> here, you're saying that "ports" is required, but you're allowing it
> to be empty..
> 
>    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:
>        - port@0
>        - port@1
> 
> ^^^ that's how it should look.
> 

Hello Angelo,

ok, I will add this.

> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> 
> As you've put it (in the example below), the max-linkrate property
> wants a value
> that corresponds to what you find in the HW registers... this is
> wrong.
> 
> Devicetree bindings should be generic and devicetrees shouldn't have
> hardware
> specific bits inside, hence, please change this property to accept a
> link rate
> specified in Mbps and also specify that in the description.
> 
> Thanks,
> Angelo
> 

ok, I will change it to real linkrate value.

BRs,
Bo-Chen

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-10  2:29       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:29 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 17:30 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >   1 file changed, 99 insertions(+)
> >   create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> 
> You should add port@0 (and port@1, probably) as required... with what
> you've done
> here, you're saying that "ports" is required, but you're allowing it
> to be empty..
> 
>    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:
>        - port@0
>        - port@1
> 
> ^^^ that's how it should look.
> 

Hello Angelo,

ok, I will add this.

> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> 
> As you've put it (in the example below), the max-linkrate property
> wants a value
> that corresponds to what you find in the HW registers... this is
> wrong.
> 
> Devicetree bindings should be generic and devicetrees shouldn't have
> hardware
> specific bits inside, hence, please change this property to accept a
> link rate
> specified in Mbps and also specify that in the description.
> 
> Thanks,
> Angelo
> 

ok, I will change it to real linkrate value.

BRs,
Bo-Chen

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-10  2:29       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:29 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 17:30 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >   1 file changed, 99 insertions(+)
> >   create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> 
> You should add port@0 (and port@1, probably) as required... with what
> you've done
> here, you're saying that "ports" is required, but you're allowing it
> to be empty..
> 
>    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:
>        - port@0
>        - port@1
> 
> ^^^ that's how it should look.
> 

Hello Angelo,

ok, I will add this.

> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> 
> As you've put it (in the example below), the max-linkrate property
> wants a value
> that corresponds to what you find in the HW registers... this is
> wrong.
> 
> Devicetree bindings should be generic and devicetrees shouldn't have
> hardware
> specific bits inside, hence, please change this property to accept a
> link rate
> specified in Mbps and also specify that in the description.
> 
> Thanks,
> Angelo
> 

ok, I will change it to real linkrate value.

BRs,
Bo-Chen

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding
@ 2022-06-10  2:29       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  2:29 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 17:30 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> > 
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   .../display/mediatek/mediatek,dp.yaml         | 99
> > +++++++++++++++++++
> >   1 file changed, 99 insertions(+)
> >   create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > new file mode 100644
> > index 000000000000..36ae0a6df299
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.ya
> > ml
> > @@ -0,0 +1,99 @@
> > +# 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 <ck.hu@mediatek.com>
> > +  - Jitao shi <jitao.shi@mediatek.com>
> > +
> > +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
> > +
> 
> You should add port@0 (and port@1, probably) as required... with what
> you've done
> here, you're saying that "ports" is required, but you're allowing it
> to be empty..
> 
>    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:
>        - port@0
>        - port@1
> 
> ^^^ that's how it should look.
> 

Hello Angelo,

ok, I will add this.

> > +  max-lanes:
> > +    maxItems: 1
> > +    description: maximum number of lanes supported by the hardware
> > +
> > +  max-linkrate:
> > +    maxItems: 1
> > +    description: maximum link rate supported by the hardware
> 
> As you've put it (in the example below), the max-linkrate property
> wants a value
> that corresponds to what you find in the HW registers... this is
> wrong.
> 
> Devicetree bindings should be generic and devicetrees shouldn't have
> hardware
> specific bits inside, hence, please change this property to accept a
> link rate
> specified in Mbps and also specify that in the description.
> 
> Thanks,
> Angelo
> 

ok, I will change it to real linkrate value.

BRs,
Bo-Chen

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +  - max-lanes
> > +  - max-linkrate
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/power/mt8195-power.h>
> > +    edp_tx: edp_tx@1c500000 {
> > +        compatible = "mediatek,mt8195-dp-tx";
> > +        reg = <0 0x1c500000 0 0x8000>;
> > +        interrupts = <GIC_SPI 676 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_EPD_TX>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&edp_pin>;
> > +        max-lanes = /bits/ 8 <4>;
> > +        max-linkrate = /bits/ 8 <0x1e>;
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                edp_in: endpoint {
> > +                    remote-endpoint = <&dp_intf0_out>;
> > +                };
> > +            };
> > +            port@1 {
> > +                reg = <1>;
> > +                edp_out: endpoint {
> > +                	remote-endpoint = <&panel_in>;
> > +                };
> > +            };
> > +        };
> > +    };
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
  2022-05-25 12:26     ` AngeloGioacchino Del Regno
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-10  6:50       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  6:50 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:26 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/drm_edid.c | 74
> > ++++++++++++++++++++++++++++++++++++++
> >   include/drm/drm_edid.h     | 14 ++++++++
> >   2 files changed, 88 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_edid.c
> > b/drivers/gpu/drm/drm_edid.c
> > index 561f53831e29..61ef1b1c972c 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4758,6 +4758,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:
> 
> As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM
> should
> never occur here?
> 

Hello Angelo,

because we do not know whether "HDMI_AUDIO_CODING_TYPE_STREAM" is
compressed, we decide to change this function name to
drm_cea_sad_is_pcm to prevent misunderstanding.
For this, I will drop case HDMI_AUDIO_CODING_TYPE_STREAM

> > +	case HDMI_AUDIO_CODING_TYPE_PCM:
> > +		return true;
> > +	default:
> > +		return false;
> > +	}
> > +}
> > +
> 
> Also, I think that implementing a
> drm_cea_sad_get_compressed_max_bitrate()
> function should be pretty straightforward... the spec says that this
> is
> 8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
> so to extract it, you read byte2 and multiply it by 8000Hz.
> 
> /**
>   * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
>   * @sad: Pointer to the cea_sad structure
>   *
>   * Extracts the cea_sad byte2 field and returns the maximum bit rate
>   * of a compressed audio stream.
>   *
>   * Note: This function may only be called for compressed audio.
>   *
>   * Return: Maximum bitrate of compressed audio stream in bit/s or
>   *         negative number for error
>   */
> int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
> {
> 	if (drm_cea_sad_is_uncompressed(sad)) {
> 		DRM_ERROR("Not supported: tried to get max bitrate for
> uncompressed format: %u\n",
> 			 sad->format);
> 		return -EINVAL;
> 	}
> 
> 	return sad->byte2 * 8000;
> }
> 

After sync with Jitao, we think this function is not correct.
refer to table of "Short Audio Descriptor" in [1].

[1]:https://en.wikipedia.org/wiki/Extended_Display_Identification_Data

BRs,
Bo-Chen
> > +/**
> > + * 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 37c420423625..7a939cb95b38 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -373,6 +373,18 @@ struct cea_sad {
> >   	u8 byte2;
> >   };
> >   
> > +#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;
> > @@ -380,6 +392,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);
> >   
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-06-10  6:50       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  6:50 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-05-25 at 14:26 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/drm_edid.c | 74
> > ++++++++++++++++++++++++++++++++++++++
> >   include/drm/drm_edid.h     | 14 ++++++++
> >   2 files changed, 88 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_edid.c
> > b/drivers/gpu/drm/drm_edid.c
> > index 561f53831e29..61ef1b1c972c 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4758,6 +4758,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:
> 
> As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM
> should
> never occur here?
> 

Hello Angelo,

because we do not know whether "HDMI_AUDIO_CODING_TYPE_STREAM" is
compressed, we decide to change this function name to
drm_cea_sad_is_pcm to prevent misunderstanding.
For this, I will drop case HDMI_AUDIO_CODING_TYPE_STREAM

> > +	case HDMI_AUDIO_CODING_TYPE_PCM:
> > +		return true;
> > +	default:
> > +		return false;
> > +	}
> > +}
> > +
> 
> Also, I think that implementing a
> drm_cea_sad_get_compressed_max_bitrate()
> function should be pretty straightforward... the spec says that this
> is
> 8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
> so to extract it, you read byte2 and multiply it by 8000Hz.
> 
> /**
>   * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
>   * @sad: Pointer to the cea_sad structure
>   *
>   * Extracts the cea_sad byte2 field and returns the maximum bit rate
>   * of a compressed audio stream.
>   *
>   * Note: This function may only be called for compressed audio.
>   *
>   * Return: Maximum bitrate of compressed audio stream in bit/s or
>   *         negative number for error
>   */
> int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
> {
> 	if (drm_cea_sad_is_uncompressed(sad)) {
> 		DRM_ERROR("Not supported: tried to get max bitrate for
> uncompressed format: %u\n",
> 			 sad->format);
> 		return -EINVAL;
> 	}
> 
> 	return sad->byte2 * 8000;
> }
> 

After sync with Jitao, we think this function is not correct.
refer to table of "Short Audio Descriptor" in [1].

[1]:https://en.wikipedia.org/wiki/Extended_Display_Identification_Data

BRs,
Bo-Chen
> > +/**
> > + * 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 37c420423625..7a939cb95b38 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -373,6 +373,18 @@ struct cea_sad {
> >   	u8 byte2;
> >   };
> >   
> > +#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;
> > @@ -380,6 +392,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);
> >   
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-06-10  6:50       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  6:50 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:26 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/drm_edid.c | 74
> > ++++++++++++++++++++++++++++++++++++++
> >   include/drm/drm_edid.h     | 14 ++++++++
> >   2 files changed, 88 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_edid.c
> > b/drivers/gpu/drm/drm_edid.c
> > index 561f53831e29..61ef1b1c972c 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4758,6 +4758,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:
> 
> As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM
> should
> never occur here?
> 

Hello Angelo,

because we do not know whether "HDMI_AUDIO_CODING_TYPE_STREAM" is
compressed, we decide to change this function name to
drm_cea_sad_is_pcm to prevent misunderstanding.
For this, I will drop case HDMI_AUDIO_CODING_TYPE_STREAM

> > +	case HDMI_AUDIO_CODING_TYPE_PCM:
> > +		return true;
> > +	default:
> > +		return false;
> > +	}
> > +}
> > +
> 
> Also, I think that implementing a
> drm_cea_sad_get_compressed_max_bitrate()
> function should be pretty straightforward... the spec says that this
> is
> 8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
> so to extract it, you read byte2 and multiply it by 8000Hz.
> 
> /**
>   * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
>   * @sad: Pointer to the cea_sad structure
>   *
>   * Extracts the cea_sad byte2 field and returns the maximum bit rate
>   * of a compressed audio stream.
>   *
>   * Note: This function may only be called for compressed audio.
>   *
>   * Return: Maximum bitrate of compressed audio stream in bit/s or
>   *         negative number for error
>   */
> int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
> {
> 	if (drm_cea_sad_is_uncompressed(sad)) {
> 		DRM_ERROR("Not supported: tried to get max bitrate for
> uncompressed format: %u\n",
> 			 sad->format);
> 		return -EINVAL;
> 	}
> 
> 	return sad->byte2 * 8000;
> }
> 

After sync with Jitao, we think this function is not correct.
refer to table of "Short Audio Descriptor" in [1].

[1]:https://en.wikipedia.org/wiki/Extended_Display_Identification_Data

BRs,
Bo-Chen
> > +/**
> > + * 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 37c420423625..7a939cb95b38 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -373,6 +373,18 @@ struct cea_sad {
> >   	u8 byte2;
> >   };
> >   
> > +#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;
> > @@ -380,6 +392,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);
> >   
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-06-10  6:50       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  6:50 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:26 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/drm_edid.c | 74
> > ++++++++++++++++++++++++++++++++++++++
> >   include/drm/drm_edid.h     | 14 ++++++++
> >   2 files changed, 88 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_edid.c
> > b/drivers/gpu/drm/drm_edid.c
> > index 561f53831e29..61ef1b1c972c 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4758,6 +4758,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:
> 
> As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM
> should
> never occur here?
> 

Hello Angelo,

because we do not know whether "HDMI_AUDIO_CODING_TYPE_STREAM" is
compressed, we decide to change this function name to
drm_cea_sad_is_pcm to prevent misunderstanding.
For this, I will drop case HDMI_AUDIO_CODING_TYPE_STREAM

> > +	case HDMI_AUDIO_CODING_TYPE_PCM:
> > +		return true;
> > +	default:
> > +		return false;
> > +	}
> > +}
> > +
> 
> Also, I think that implementing a
> drm_cea_sad_get_compressed_max_bitrate()
> function should be pretty straightforward... the spec says that this
> is
> 8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
> so to extract it, you read byte2 and multiply it by 8000Hz.
> 
> /**
>   * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
>   * @sad: Pointer to the cea_sad structure
>   *
>   * Extracts the cea_sad byte2 field and returns the maximum bit rate
>   * of a compressed audio stream.
>   *
>   * Note: This function may only be called for compressed audio.
>   *
>   * Return: Maximum bitrate of compressed audio stream in bit/s or
>   *         negative number for error
>   */
> int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
> {
> 	if (drm_cea_sad_is_uncompressed(sad)) {
> 		DRM_ERROR("Not supported: tried to get max bitrate for
> uncompressed format: %u\n",
> 			 sad->format);
> 		return -EINVAL;
> 	}
> 
> 	return sad->byte2 * 8000;
> }
> 

After sync with Jitao, we think this function is not correct.
refer to table of "Short Audio Descriptor" in [1].

[1]:https://en.wikipedia.org/wiki/Extended_Display_Identification_Data

BRs,
Bo-Chen
> > +/**
> > + * 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 37c420423625..7a939cb95b38 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -373,6 +373,18 @@ struct cea_sad {
> >   	u8 byte2;
> >   };
> >   
> > +#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;
> > @@ -380,6 +392,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);
> >   
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length
@ 2022-06-10  6:50       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-10  6:50 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:26 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/drm_edid.c | 74
> > ++++++++++++++++++++++++++++++++++++++
> >   include/drm/drm_edid.h     | 14 ++++++++
> >   2 files changed, 88 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_edid.c
> > b/drivers/gpu/drm/drm_edid.c
> > index 561f53831e29..61ef1b1c972c 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4758,6 +4758,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:
> 
> As far as I know, bit 0 is reserved, so HDMI_AUDIO_CODING_TYPE_STREAM
> should
> never occur here?
> 

Hello Angelo,

because we do not know whether "HDMI_AUDIO_CODING_TYPE_STREAM" is
compressed, we decide to change this function name to
drm_cea_sad_is_pcm to prevent misunderstanding.
For this, I will drop case HDMI_AUDIO_CODING_TYPE_STREAM

> > +	case HDMI_AUDIO_CODING_TYPE_PCM:
> > +		return true;
> > +	default:
> > +		return false;
> > +	}
> > +}
> > +
> 
> Also, I think that implementing a
> drm_cea_sad_get_compressed_max_bitrate()
> function should be pretty straightforward... the spec says that this
> is
> 8 bits, byte 3 (your byte2) contains the max bitrate divided by 8kHz,
> so to extract it, you read byte2 and multiply it by 8000Hz.
> 
> /**
>   * drm_cea_sad_get_compressed_max_bitrate - Extract maximum bitrate
>   * @sad: Pointer to the cea_sad structure
>   *
>   * Extracts the cea_sad byte2 field and returns the maximum bit rate
>   * of a compressed audio stream.
>   *
>   * Note: This function may only be called for compressed audio.
>   *
>   * Return: Maximum bitrate of compressed audio stream in bit/s or
>   *         negative number for error
>   */
> int drm_cea_sad_get_compressed_max_bitrate(const struct cea_sad *sad)
> {
> 	if (drm_cea_sad_is_uncompressed(sad)) {
> 		DRM_ERROR("Not supported: tried to get max bitrate for
> uncompressed format: %u\n",
> 			 sad->format);
> 		return -EINVAL;
> 	}
> 
> 	return sad->byte2 * 8000;
> }
> 

After sync with Jitao, we think this function is not correct.
refer to table of "Short Audio Descriptor" in [1].

[1]:https://en.wikipedia.org/wiki/Extended_Display_Identification_Data

BRs,
Bo-Chen
> > +/**
> > + * 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 37c420423625..7a939cb95b38 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -373,6 +373,18 @@ struct cea_sad {
> >   	u8 byte2;
> >   };
> >   
> > +#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;
> > @@ -380,6 +392,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);
> >   
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
  2022-05-30  7:50     ` CK Hu
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-13  3:12       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  3:12 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 15:50 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without swap_input
> > support
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
> >  1 file changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 545a1337cc89..454f8563efae 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> >  	bool is_ck_de_pol;
> > +	bool swap_input_support;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -378,18 +379,21 @@ static void
> > mtk_dpi_config_color_format(struct
> > mtk_dpi *dpi,
> >  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_BGR);
> >  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
> >  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, true);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, true);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, true);
> 
> As [1], please keep in touch with Mediatek engineer.
> 
> Regards,
> CK
> 
> [1] 
> 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/
> 

Hello CK,

the reason is the hardware design of dp_intf does not support input
swap.
I will add this in commit message.

BRs,
Bo-Chen

> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	} else {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, false);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	}
> >  }
> > @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-06-13  3:12       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  3:12 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel, linux-mediatek,
	linux-phy, linux-arm-kernel, AngeloGioacchino Del Regno

On Mon, 2022-05-30 at 15:50 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without swap_input
> > support
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
> >  1 file changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 545a1337cc89..454f8563efae 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> >  	bool is_ck_de_pol;
> > +	bool swap_input_support;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -378,18 +379,21 @@ static void
> > mtk_dpi_config_color_format(struct
> > mtk_dpi *dpi,
> >  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_BGR);
> >  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
> >  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, true);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, true);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, true);
> 
> As [1], please keep in touch with Mediatek engineer.
> 
> Regards,
> CK
> 
> [1] 
> 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/
> 

Hello CK,

the reason is the hardware design of dp_intf does not support input
swap.
I will add this in commit message.

BRs,
Bo-Chen

> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	} else {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, false);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	}
> >  }
> > @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-06-13  3:12       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  3:12 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 15:50 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without swap_input
> > support
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
> >  1 file changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 545a1337cc89..454f8563efae 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> >  	bool is_ck_de_pol;
> > +	bool swap_input_support;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -378,18 +379,21 @@ static void
> > mtk_dpi_config_color_format(struct
> > mtk_dpi *dpi,
> >  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_BGR);
> >  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
> >  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, true);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, true);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, true);
> 
> As [1], please keep in touch with Mediatek engineer.
> 
> Regards,
> CK
> 
> [1] 
> 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/
> 

Hello CK,

the reason is the hardware design of dp_intf does not support input
swap.
I will add this in commit message.

BRs,
Bo-Chen

> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	} else {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, false);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	}
> >  }
> > @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-06-13  3:12       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  3:12 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 15:50 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without swap_input
> > support
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
> >  1 file changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 545a1337cc89..454f8563efae 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> >  	bool is_ck_de_pol;
> > +	bool swap_input_support;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -378,18 +379,21 @@ static void
> > mtk_dpi_config_color_format(struct
> > mtk_dpi *dpi,
> >  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_BGR);
> >  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
> >  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, true);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, true);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, true);
> 
> As [1], please keep in touch with Mediatek engineer.
> 
> Regards,
> CK
> 
> [1] 
> 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/
> 

Hello CK,

the reason is the hardware design of dp_intf does not support input
swap.
I will add this in commit message.

BRs,
Bo-Chen

> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	} else {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, false);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	}
> >  }
> > @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
@ 2022-06-13  3:12       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  3:12 UTC (permalink / raw)
  To: CK Hu, Guillaume Ranquet, Chun-Kuang Hu, Philipp Zabel,
	David Airlie, Daniel Vetter, Rob Herring, Krzysztof Kozlowski,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Matthias Brugger, Chunfeng Yun, Kishon Vijay Abraham I,
	Vinod Koul, Helge Deller, Jitao shi
  Cc: AngeloGioacchino Del Regno, dri-devel, linux-mediatek,
	devicetree, linux-kernel, linux-arm-kernel, linux-phy,
	linux-fbdev

On Mon, 2022-05-30 at 15:50 +0800, CK Hu wrote:
> Hi, Guillaume:
> 
> 
> On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote:
> > Adds a bit of flexibility to support SoCs without swap_input
> > support
> > 
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno@collabora.com>
> > Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++++++++++---
> >  1 file changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 545a1337cc89..454f8563efae 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
> >  	const u32 *output_fmts;
> >  	u32 num_output_fmts;
> >  	bool is_ck_de_pol;
> > +	bool swap_input_support;
> >  	const struct mtk_dpi_yc_limit *limit;
> >  };
> >  
> > @@ -378,18 +379,21 @@ static void
> > mtk_dpi_config_color_format(struct
> > mtk_dpi *dpi,
> >  	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_BGR);
> >  	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
> >  		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
> >  		mtk_dpi_config_yuv422_enable(dpi, true);
> >  		mtk_dpi_config_csc_enable(dpi, true);
> > -		mtk_dpi_config_swap_input(dpi, true);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, true);
> 
> As [1], please keep in touch with Mediatek engineer.
> 
> Regards,
> CK
> 
> [1] 
> 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220218145437.18563-8-granquet@baylibre.com/
> 

Hello CK,

the reason is the hardware design of dp_intf does not support input
swap.
I will add this in commit message.

BRs,
Bo-Chen

> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	} else {
> >  		mtk_dpi_config_yuv422_enable(dpi, false);
> >  		mtk_dpi_config_csc_enable(dpi, false);
> > -		mtk_dpi_config_swap_input(dpi, false);
> > +		if (dpi->conf->swap_input_support)
> > +			mtk_dpi_config_swap_input(dpi, false);
> >  		mtk_dpi_config_channel_swap(dpi,
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> >  	}
> >  }
> > @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf =
> > {
> >  	.output_fmts = mt8183_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> > @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >  	.output_fmts = mt8173_output_fmts,
> >  	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> >  	.is_ck_de_pol = true,
> > +	.swap_input_support = true,
> >  	.limit = &mtk_dpi_limit,
> >  };
> >  
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
  2022-06-02  5:48     ` Christophe JAILLET
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-13  6:05       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:05 UTC (permalink / raw)
  To: Christophe JAILLET, granquet
  Cc: airlied, chunfeng.yun, chunkuang.hu, ck.hu, daniel, deller,
	devicetree, dri-devel, jitao.shi, kishon, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-fbdev, linux-kernel, linux-mediatek,
	linux-phy, maarten.lankhorst, matthias.bgg, mripard, msp,
	p.zabel, robh+dt, tzimmermann, vkoul

On Thu, 2022-06-02 at 07:48 +0200, Christophe JAILLET wrote:
> Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> > 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > .
> > 
> > Signed-off-by: Markus Schneider-Pargmann <
> > msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > Signed-off-by: Guillaume Ranquet <
> > granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> 
> Hi,
> 
> belwo the error handling path looks odd. (both where we goto, and
> the 
> order of the clk_disable_unprepare() in the error handling path.
> 
> just my 2c,
> 
> CJ
> 

Hello Christophe,

Thanks for your review.
I will fix this order in enxt version.

Thanks

BRs,
Bo-Chen

> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> 
> [...]
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-13  6:05       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:05 UTC (permalink / raw)
  To: Christophe JAILLET, granquet
  Cc: linux-fbdev, devicetree, airlied, dri-devel,
	krzysztof.kozlowski+dt, linux-phy, deller, kishon, chunkuang.hu,
	jitao.shi, msp, chunfeng.yun, robh+dt, linux-mediatek,
	matthias.bgg, linux-arm-kernel, tzimmermann, linux-kernel, vkoul

On Thu, 2022-06-02 at 07:48 +0200, Christophe JAILLET wrote:
> Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> > 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > .
> > 
> > Signed-off-by: Markus Schneider-Pargmann <
> > msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > Signed-off-by: Guillaume Ranquet <
> > granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> 
> Hi,
> 
> belwo the error handling path looks odd. (both where we goto, and
> the 
> order of the clk_disable_unprepare() in the error handling path.
> 
> just my 2c,
> 
> CJ
> 

Hello Christophe,

Thanks for your review.
I will fix this order in enxt version.

Thanks

BRs,
Bo-Chen

> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> 
> [...]
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-13  6:05       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:05 UTC (permalink / raw)
  To: Christophe JAILLET, granquet
  Cc: airlied, chunfeng.yun, chunkuang.hu, ck.hu, daniel, deller,
	devicetree, dri-devel, jitao.shi, kishon, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-fbdev, linux-kernel, linux-mediatek,
	linux-phy, maarten.lankhorst, matthias.bgg, mripard, msp,
	p.zabel, robh+dt, tzimmermann, vkoul

On Thu, 2022-06-02 at 07:48 +0200, Christophe JAILLET wrote:
> Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> > 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > .
> > 
> > Signed-off-by: Markus Schneider-Pargmann <
> > msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > Signed-off-by: Guillaume Ranquet <
> > granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> 
> Hi,
> 
> belwo the error handling path looks odd. (both where we goto, and
> the 
> order of the clk_disable_unprepare() in the error handling path.
> 
> just my 2c,
> 
> CJ
> 

Hello Christophe,

Thanks for your review.
I will fix this order in enxt version.

Thanks

BRs,
Bo-Chen

> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> 
> [...]
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-13  6:05       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:05 UTC (permalink / raw)
  To: Christophe JAILLET, granquet
  Cc: airlied, chunfeng.yun, chunkuang.hu, ck.hu, daniel, deller,
	devicetree, dri-devel, jitao.shi, kishon, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-fbdev, linux-kernel, linux-mediatek,
	linux-phy, maarten.lankhorst, matthias.bgg, mripard, msp,
	p.zabel, robh+dt, tzimmermann, vkoul

On Thu, 2022-06-02 at 07:48 +0200, Christophe JAILLET wrote:
> Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> > 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > .
> > 
> > Signed-off-by: Markus Schneider-Pargmann <
> > msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > Signed-off-by: Guillaume Ranquet <
> > granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> 
> Hi,
> 
> belwo the error handling path looks odd. (both where we goto, and
> the 
> order of the clk_disable_unprepare() in the error handling path.
> 
> just my 2c,
> 
> CJ
> 

Hello Christophe,

Thanks for your review.
I will fix this order in enxt version.

Thanks

BRs,
Bo-Chen

> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> 
> [...]
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-13  6:05       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:05 UTC (permalink / raw)
  To: Christophe JAILLET, granquet
  Cc: airlied, chunfeng.yun, chunkuang.hu, ck.hu, daniel, deller,
	devicetree, dri-devel, jitao.shi, kishon, krzysztof.kozlowski+dt,
	linux-arm-kernel, linux-fbdev, linux-kernel, linux-mediatek,
	linux-phy, maarten.lankhorst, matthias.bgg, mripard, msp,
	p.zabel, robh+dt, tzimmermann, vkoul

On Thu, 2022-06-02 at 07:48 +0200, Christophe JAILLET wrote:
> Le 23/05/2022 à 12:47, Guillaume Ranquet a écrit :
> > 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 <jason-jh.lin-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > .
> > 
> > Signed-off-by: Markus Schneider-Pargmann <
> > msp-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > Signed-off-by: Guillaume Ranquet <
> > granquet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> 
> Hi,
> 
> belwo the error handling path looks odd. (both where we goto, and
> the 
> order of the clk_disable_unprepare() in the error handling path.
> 
> just my 2c,
> 
> CJ
> 

Hello Christophe,

Thanks for your review.
I will fix this order in enxt version.

Thanks

BRs,
Bo-Chen

> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> 
> [...]
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
  2022-05-25 12:58     ` AngeloGioacchino Del Regno
                         ` (2 preceding siblings ...)
  (?)
@ 2022-06-13  6:10       ` Rex-BC Chen
  -1 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: devicetree, linux-fbdev, linux-kernel, dri-devel,
	Markus Schneider-Pargmann, linux-mediatek, linux-phy,
	linux-arm-kernel

On Wed, 2022-05-25 at 14:58 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> 
> Only after finishing the review, I've noticed that I just wrote the
> same things
> that I wrote in my review for version 8... and if I recall correctly,
> this is not
> the first time that something like that happens.
> 
> Please pay attention to what reviewers say, as to not waste anyone's
> time.
> 

Hello Angelo,

I will help to fix these issue in next version.

> 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> > @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   
> >   	vm.pixelclock = pll_rate / factor;
> >   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> > -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> > +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
> 
> The indentation was perfect before that change...
> 
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> > -	else
> > +	} else {
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> > -
> > +	}
> >   
> >   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
> >   
> > @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> >   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> > -	hsync.sync_width = vm.hsync_len;
> > -	hsync.back_porch = vm.hback_porch;
> > -	hsync.front_porch = vm.hfront_porch;
> > +	if (dpi->conf->is_dpintf) {
> > +		hsync.sync_width = vm.hsync_len / 4;
> > +		hsync.back_porch = vm.hback_porch / 4;
> > +		hsync.front_porch = vm.hfront_porch / 4;
> > +	} else {
> > +		hsync.sync_width = vm.hsync_len;
> > +		hsync.back_porch = vm.hback_porch;
> > +		hsync.front_porch = vm.hfront_porch;
> > +	}
> 
> This looks way better:
> 
> 	hsync.sync_width = vm.hsync_len;
> 	hsync.back_porch = vm.hback_porch;
> 	hsync.front_porch = vm.hfront_porch;
> 
> 	/* For DPINTF, we need to divide everything by 4 .. lanes? */
> 	if (dpi->conf->is_dpintf) {
> 		hsync.sync_width /= 4;
> 		hsync.back_porch /= 4;
> 		hsync.front_porch /= 4;
> 	}
> 

ok.

> >   	hsync.shift_half_line = false;
> >   	vsync_lodd.sync_width = vm.vsync_len;
> >   	vsync_lodd.back_porch = vm.vback_porch;
> > @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   	mtk_dpi_config_channel_limit(dpi);
> >   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> >   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> > -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> >   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> > -	mtk_dpi_config_2n_h_fre(dpi);
> > -	mtk_dpi_dual_edge(dpi);
> > -	mtk_dpi_config_disable_edge(dpi);
> > +	if (dpi->conf->is_dpintf) {
> > +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> > +			     DPINTF_INPUT_2P_EN);
> > +	} else {
> > +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> > +		mtk_dpi_config_2n_h_fre(dpi);
> > +		mtk_dpi_dual_edge(dpi);
> > +		mtk_dpi_config_disable_edge(dpi);
> > +	}
> >   	mtk_dpi_sw_reset(dpi, false);
> >   
> > +	mtk_dpi_enable(dpi);
> > +
> >   	return 0;
> >   }
> >   
> > @@ -608,7 +639,6 @@ static u32
> > *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge
> > *bridge,
> >   	u32 *input_fmts;
> >   
> >   	*num_input_fmts = 0;
> > -
> 
> Removing this line is not part of adding dpintf support, so don't do
> that.
> 

ok.

> >   	input_fmts = kcalloc(1, sizeof(*input_fmts),
> >   			     GFP_KERNEL);
> >   	if (!input_fmts)
> > @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct
> > drm_bridge *bridge,
> >   		if (dpi->conf->num_output_fmts)
> >   			out_bus_format = dpi->conf->output_fmts[0];
> >   
> > -	dev_dbg(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > -		bridge_state->input_bus_cfg.format,
> > -		bridge_state->output_bus_cfg.format);
> > +	dev_info(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > +		 bridge_state->input_bus_cfg.format,
> > +		 bridge_state->output_bus_cfg.format);
> 
> This message is not giving any constantly changing information, nor
> any one that
> is interesting for the user: keep this as dev_dbg().
> 

ok.

> >   
> >   	dpi->output_fmt = out_bus_format;
> >   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
> >   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
> >   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> > -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> > +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> > +		dpi->color_format =
> > MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> > +	else
> > +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> >   
> >   	return 0;
> >   }
> > @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge
> > *bridge,
> >   {
> >   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
> >   
> > -	if (mode->clock > dpi->conf->max_clock_khz)
> > +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf-
> > >max_clock_khz)
> >   		return MODE_CLOCK_HIGH;
> >   
> >   	return MODE_OK;
> > @@ -801,6 +834,16 @@ static unsigned int
> > mt8183_calculate_factor(int clock)
> >   		return 2;
> >   }
> >   
> > +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> > +{
> > +	if (clock < 70000)
> 
> is 70000 intentional? Or did you mean 700000?
> 

70000 is correct, the unit for this is KHz.


> > +		return 4;
> > +	else if (clock < 200000)
> > +		return 2;
> > +	else
> > +		return 1;
> > +}
> > +
> >   static const u32 mt8173_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_1X24,
> >   };
> > @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_2X12_BE,
> >   };
> >   
> > +static const u32 mt8195_output_fmts[] = {
> > +	MEDIA_BUS_FMT_RGB888_1X24,
> > +	MEDIA_BUS_FMT_YUV8_1X24,
> > +	MEDIA_BUS_FMT_YUYV8_1X16,
> > +};
> > +
> >   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
> >   	.c_bottom = 0x0010,
> >   	.c_top = 0x0FE0,
> > @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit
> > mtk_dpi_limit = {
> >   	.y_top = 0x0FE0,
> >   };
> >   
> > +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> > +	.c_bottom = 0x0000,
> > +	.c_top = 0xFFF,
> > +	.y_bottom = 0x0000,
> > +	.y_top = 0xFFF,
> > +};
> > +
> >   static const struct mtk_dpi_conf mt8173_conf = {
> >   	.cal_factor = mt8173_calculate_factor,
> >   	.reg_h_fre_con = 0xe0,
> > @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >   	.limit = &mtk_dpi_limit,
> >   };
> >   
> > +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> > +	.cal_factor = mt8195_dpintf_calculate_factor,
> > +	.output_fmts = mt8195_output_fmts,
> > +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> > +	.is_dpintf = true,
> > +	.dimension_mask = DPINTF_HPW_MASK,
> > +	.hvsize_mask = DPINTF_HSIZE_MASK,
> > +	.channel_swap_shift = DPINTF_CH_SWAP,
> > +	.yuv422_en_bit = DPINTF_YUV422_EN,
> > +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> > +	.limit = &mtk_dpintf_limit,
> > +};
> > +
> >   static int mtk_dpi_probe(struct platform_device *pdev)
> >   {
> >   	struct device *dev = &pdev->dev;
> > @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct
> > platform_device *pdev)
> >   	if (IS_ERR(dpi->engine_clk)) {
> >   		ret = PTR_ERR(dpi->engine_clk);
> >   		if (ret != -EPROBE_DEFER)
> > -			dev_err(dev, "Failed to get engine clock:
> > %d\n", ret);
> > +			dev_err(dev, "Failed to get engine clock:
> > %d\n",
> > +				ret);
> 
> Why are you breaking this line?
> 

I will fix this.

> > +
> > +		return ret;
> > +	}
> > +
> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n",
> > +				ret);
> > +
> > +		return ret;
> > +	}
> > +
> 
> You're getting this clock twice, what happened here?
> 
> P.S.: As I explained on the dt-bindings patch, you likely don't even
> need this
>        clock at all.
> 

I will remove this.
For this clock gate, we stiil need to enable it.

I reply in binding patch.

I rename it as pll_gate.

> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n", ret);
> >   
> >   		return ret;
> >   	}
> > @@ -1004,6 +1093,9 @@ static const struct of_device_id
> > mtk_dpi_of_ids[] = {
> >   	{ .compatible = "mediatek,mt8192-dpi",
> >   	  .data = &mt8192_conf,
> >   	},
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = &mt8195_dpintf_conf,
> > +	},
> >   	{ },
> >   };
> >   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > index 3a02fabe1662..dd47dd3f2e4f 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > @@ -40,10 +40,15 @@
> >   #define FAKE_DE_LEVEN			BIT(21)
> >   #define FAKE_DE_RODD			BIT(22)
> >   #define FAKE_DE_REVEN			BIT(23)
> > +#define DPINTF_YUV422_EN		BIT(24)
> > +#define DPINTF_CSC_ENABLE		BIT(26)
> > +#define DPINTF_INPUT_2P_EN		BIT(29)
> >   
> >   #define DPI_OUTPUT_SETTING	0x14
> >   #define CH_SWAP				0
> > +#define DPINTF_CH_SWAP			BIT(1)
> >   #define CH_SWAP_MASK			(0x7 << 0)
> > +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> >   #define SWAP_RGB			0x00
> >   #define SWAP_GBR			0x01
> >   #define SWAP_BRG			0x02
> > @@ -80,8 +85,10 @@
> >   #define DPI_SIZE		0x18
> >   #define HSIZE				0
> >   #define HSIZE_MASK			(0x1FFF << 0)
> > +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
> >   #define VSIZE				16
> >   #define VSIZE_MASK			(0x1FFF << 16)
> > +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
> >   
> >   #define DPI_DDR_SETTING		0x1C
> >   #define DDR_EN				BIT(0)
> > @@ -93,24 +100,30 @@
> >   #define DPI_TGEN_HWIDTH		0x20
> >   #define HPW				0
> >   #define HPW_MASK			(0xFFF << 0)
> > +#define DPINTF_HPW_MASK			(0xFFFF << 0)
> >   
> >   #define DPI_TGEN_HPORCH		0x24
> >   #define HBP				0
> >   #define HBP_MASK			(0xFFF << 0)
> > +#define DPINTF_HBP_MASK			(0xFFFF << 0)
> >   #define HFP				16
> >   #define HFP_MASK			(0xFFF << 16)
> > +#define DPINTF_HFP_MASK			(0xFFFF << 16)
> >   
> >   #define DPI_TGEN_VWIDTH		0x28
> >   #define DPI_TGEN_VPORCH		0x2C
> >   
> >   #define VSYNC_WIDTH_SHIFT		0
> >   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
> >   #define VSYNC_HALF_LINE_SHIFT		16
> >   #define VSYNC_HALF_LINE_MASK		BIT(16)
> >   #define VSYNC_BACK_PORCH_SHIFT		0
> >   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
> >   #define VSYNC_FRONT_PORCH_SHIFT		16
> >   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> > +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
> >   
> >   #define DPI_BG_HCNTL		0x30
> >   #define BG_RIGHT			(0x1FFF << 0)
> > @@ -217,4 +230,26 @@
> >   
> >   #define EDGE_SEL_EN			BIT(5)
> >   #define H_FRE_2N			BIT(25)
> > +
> > +#define RGB_TO_JPEG			0x00
> 
> This is 0x0
> 
> > +#define RGB_TO_FULL709			0x01
> 
> 0x1
> 
> > +#define RGB_TO_BT601			0x02
> 
> 0x2
> 
> ...remove the unnecessary leading zeros, but... you're not ever
> using this set of definitions, so why are you even adding them?
> 

ok, I will remove them.

> > +#define RGB_TO_BT709			0x03
> > +#define JPEG_TO_RGB			0x04
> > +#define FULL709_TO_RGB			0x05
> > +#define BT601_TO_RGB			0x06
> > +#define BT709_TO_RGB			0x07
> > +#define JPEG_TO_BT601			0x08
> > +#define JPEG_TO_BT709			0x09
> > +#define BT601_TO_JPEG			0xA
> > +#define BT709_TO_JPEG			0xB
> > +#define BT709_TO_BT601			0xC
> > +#define BT601_TO_BT709			0xD
> > +#define JPEG_TO_CERGB			0x14
> > +#define FULL709_TO_CERGB		0x15
> > +#define BT601_TO_CERGB			0x16
> > +#define BT709_TO_CERGB			0x17
> > +#define RGB_TO_CERGB			0x1C
> > +#define MATRIX_BIT			BIT(8)
> > +#define EXT_MATRIX_EN			BIT(12)
> >   #endif /* __MTK_DPI_REGS_H */
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 245d0074e12d..3738665a712e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -419,6 +419,11 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >   	[MTK_DISP_WDMA] = "wdma",
> >   	[MTK_DPI] = "dpi",
> >   	[MTK_DSI] = "dsi",
> > +	[MTK_DP_INTF] = "dp-intf",
> > +	[MTK_DISP_PWM] = "pwm",
> > +	[MTK_DISP_MUTEX] = "mutex",
> > +	[MTK_DISP_OD] = "od",
> > +	[MTK_DISP_BLS] = "bls",
> 
> Please keep alphabetic order.
> 

Some of this are redundant, and I will remove them.

> >   };
> >   
> >   struct mtk_ddp_comp_match {
> > @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			
> > 1, &ddp_dpi },
> >   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		
> > 0, &ddp_dsc },
> >   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		
> > 1, &ddp_dsc },
> > +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi
> > },
> > +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi
> > },
> 
> Indentation issue. Fix it.
> 

Some of this are redundant, and I will remove them.

> >   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			
> > 0, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			
> > 1, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			
> > 2, &ddp_dsi },
> > @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node,
> > struct mtk_ddp_comp *comp,
> >   	    type == MTK_DISP_PWM ||
> >   	    type == MTK_DISP_RDMA ||
> >   	    type == MTK_DPI ||
> > +	    type == MTK_DP_INTF ||
> >   	    type == MTK_DSI)
> >   		return 0;
> >   
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index 825d763d2378..c4e683f46a95 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
> >   	MTK_DISP_UFOE,
> >   	MTK_DISP_WDMA,
> >   	MTK_DPI,
> > +	MTK_DP_INTF,
> >   	MTK_DSI,
> >   	MTK_DDP_COMP_TYPE_MAX,
> >   };
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index a2a783fc580e..e25ac61aac08 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -690,6 +690,8 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >   	  .data = (void *)MTK_DPI },
> >   	{ .compatible = "mediatek,mt8183-dpi",
> >   	  .data = (void *)MTK_DPI },
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = (void *)MTK_DP_INTF },
> >   	{ .compatible = "mediatek,mt2701-dsi",
> >   	  .data = (void *)MTK_DSI },
> >   	{ .compatible = "mediatek,mt8173-dsi",
> > @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device
> > *pdev)
> >   		    comp_type == MTK_DISP_OVL_2L ||
> >   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
> >   		    comp_type == MTK_DISP_RDMA ||
> > +		    comp_type == MTK_DSI ||
> >   		    comp_type == MTK_DPI ||
> > -		    comp_type == MTK_DSI) {
> > +		    comp_type == MTK_DP_INTF) {
> 
> These were nice and alphabetically ordered, why are you moving
> MTK_DSI up there?!
> 
>   		    comp_type == MTK_DISP_RDMA ||
> 		    comp_type == MTK_DP_INTF ||
>   		    comp_type == MTK_DPI ||
> 		    comp_type == MTK_DSI) {
> 
> ... that's how it should look like.
> 

Some of this are redundant, and I will remove them.

> >   			dev_info(dev, "Adding component match for
> > %pOF\n",
> >   				 node);
> >   			drm_of_component_match_add(dev, &match,
> > component_compare_of,
> > diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> > b/include/linux/soc/mediatek/mtk-mmsys.h
> > index 3e998bfb795a..e4b84c347201 100644
> > --- a/include/linux/soc/mediatek/mtk-mmsys.h
> > +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> > @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
> >   	DDP_COMPONENT_COLOR0,
> >   	DDP_COMPONENT_COLOR1,
> >   	DDP_COMPONENT_DITHER,
> > -	DDP_COMPONENT_DP_INTF0,
> > -	DDP_COMPONENT_DP_INTF1,
> >   	DDP_COMPONENT_DPI0,
> >   	DDP_COMPONENT_DPI1,
> >   	DDP_COMPONENT_DSC0,
> >   	DDP_COMPONENT_DSC1,
> > +	DDP_COMPONENT_DP_INTF0,
> > +	DDP_COMPONENT_DP_INTF1,
> 
> Why are you moving this?!
> 

I will fix this.

BRs,
Bo-Chen

> >   	DDP_COMPONENT_DSI0,
> >   	DDP_COMPONENT_DSI1,
> >   	DDP_COMPONENT_DSI2,
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-13  6:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:58 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> 
> Only after finishing the review, I've noticed that I just wrote the
> same things
> that I wrote in my review for version 8... and if I recall correctly,
> this is not
> the first time that something like that happens.
> 
> Please pay attention to what reviewers say, as to not waste anyone's
> time.
> 

Hello Angelo,

I will help to fix these issue in next version.

> 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> > @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   
> >   	vm.pixelclock = pll_rate / factor;
> >   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> > -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> > +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
> 
> The indentation was perfect before that change...
> 
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> > -	else
> > +	} else {
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> > -
> > +	}
> >   
> >   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
> >   
> > @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> >   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> > -	hsync.sync_width = vm.hsync_len;
> > -	hsync.back_porch = vm.hback_porch;
> > -	hsync.front_porch = vm.hfront_porch;
> > +	if (dpi->conf->is_dpintf) {
> > +		hsync.sync_width = vm.hsync_len / 4;
> > +		hsync.back_porch = vm.hback_porch / 4;
> > +		hsync.front_porch = vm.hfront_porch / 4;
> > +	} else {
> > +		hsync.sync_width = vm.hsync_len;
> > +		hsync.back_porch = vm.hback_porch;
> > +		hsync.front_porch = vm.hfront_porch;
> > +	}
> 
> This looks way better:
> 
> 	hsync.sync_width = vm.hsync_len;
> 	hsync.back_porch = vm.hback_porch;
> 	hsync.front_porch = vm.hfront_porch;
> 
> 	/* For DPINTF, we need to divide everything by 4 .. lanes? */
> 	if (dpi->conf->is_dpintf) {
> 		hsync.sync_width /= 4;
> 		hsync.back_porch /= 4;
> 		hsync.front_porch /= 4;
> 	}
> 

ok.

> >   	hsync.shift_half_line = false;
> >   	vsync_lodd.sync_width = vm.vsync_len;
> >   	vsync_lodd.back_porch = vm.vback_porch;
> > @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   	mtk_dpi_config_channel_limit(dpi);
> >   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> >   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> > -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> >   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> > -	mtk_dpi_config_2n_h_fre(dpi);
> > -	mtk_dpi_dual_edge(dpi);
> > -	mtk_dpi_config_disable_edge(dpi);
> > +	if (dpi->conf->is_dpintf) {
> > +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> > +			     DPINTF_INPUT_2P_EN);
> > +	} else {
> > +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> > +		mtk_dpi_config_2n_h_fre(dpi);
> > +		mtk_dpi_dual_edge(dpi);
> > +		mtk_dpi_config_disable_edge(dpi);
> > +	}
> >   	mtk_dpi_sw_reset(dpi, false);
> >   
> > +	mtk_dpi_enable(dpi);
> > +
> >   	return 0;
> >   }
> >   
> > @@ -608,7 +639,6 @@ static u32
> > *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge
> > *bridge,
> >   	u32 *input_fmts;
> >   
> >   	*num_input_fmts = 0;
> > -
> 
> Removing this line is not part of adding dpintf support, so don't do
> that.
> 

ok.

> >   	input_fmts = kcalloc(1, sizeof(*input_fmts),
> >   			     GFP_KERNEL);
> >   	if (!input_fmts)
> > @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct
> > drm_bridge *bridge,
> >   		if (dpi->conf->num_output_fmts)
> >   			out_bus_format = dpi->conf->output_fmts[0];
> >   
> > -	dev_dbg(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > -		bridge_state->input_bus_cfg.format,
> > -		bridge_state->output_bus_cfg.format);
> > +	dev_info(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > +		 bridge_state->input_bus_cfg.format,
> > +		 bridge_state->output_bus_cfg.format);
> 
> This message is not giving any constantly changing information, nor
> any one that
> is interesting for the user: keep this as dev_dbg().
> 

ok.

> >   
> >   	dpi->output_fmt = out_bus_format;
> >   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
> >   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
> >   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> > -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> > +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> > +		dpi->color_format =
> > MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> > +	else
> > +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> >   
> >   	return 0;
> >   }
> > @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge
> > *bridge,
> >   {
> >   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
> >   
> > -	if (mode->clock > dpi->conf->max_clock_khz)
> > +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf-
> > >max_clock_khz)
> >   		return MODE_CLOCK_HIGH;
> >   
> >   	return MODE_OK;
> > @@ -801,6 +834,16 @@ static unsigned int
> > mt8183_calculate_factor(int clock)
> >   		return 2;
> >   }
> >   
> > +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> > +{
> > +	if (clock < 70000)
> 
> is 70000 intentional? Or did you mean 700000?
> 

70000 is correct, the unit for this is KHz.


> > +		return 4;
> > +	else if (clock < 200000)
> > +		return 2;
> > +	else
> > +		return 1;
> > +}
> > +
> >   static const u32 mt8173_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_1X24,
> >   };
> > @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_2X12_BE,
> >   };
> >   
> > +static const u32 mt8195_output_fmts[] = {
> > +	MEDIA_BUS_FMT_RGB888_1X24,
> > +	MEDIA_BUS_FMT_YUV8_1X24,
> > +	MEDIA_BUS_FMT_YUYV8_1X16,
> > +};
> > +
> >   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
> >   	.c_bottom = 0x0010,
> >   	.c_top = 0x0FE0,
> > @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit
> > mtk_dpi_limit = {
> >   	.y_top = 0x0FE0,
> >   };
> >   
> > +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> > +	.c_bottom = 0x0000,
> > +	.c_top = 0xFFF,
> > +	.y_bottom = 0x0000,
> > +	.y_top = 0xFFF,
> > +};
> > +
> >   static const struct mtk_dpi_conf mt8173_conf = {
> >   	.cal_factor = mt8173_calculate_factor,
> >   	.reg_h_fre_con = 0xe0,
> > @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >   	.limit = &mtk_dpi_limit,
> >   };
> >   
> > +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> > +	.cal_factor = mt8195_dpintf_calculate_factor,
> > +	.output_fmts = mt8195_output_fmts,
> > +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> > +	.is_dpintf = true,
> > +	.dimension_mask = DPINTF_HPW_MASK,
> > +	.hvsize_mask = DPINTF_HSIZE_MASK,
> > +	.channel_swap_shift = DPINTF_CH_SWAP,
> > +	.yuv422_en_bit = DPINTF_YUV422_EN,
> > +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> > +	.limit = &mtk_dpintf_limit,
> > +};
> > +
> >   static int mtk_dpi_probe(struct platform_device *pdev)
> >   {
> >   	struct device *dev = &pdev->dev;
> > @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct
> > platform_device *pdev)
> >   	if (IS_ERR(dpi->engine_clk)) {
> >   		ret = PTR_ERR(dpi->engine_clk);
> >   		if (ret != -EPROBE_DEFER)
> > -			dev_err(dev, "Failed to get engine clock:
> > %d\n", ret);
> > +			dev_err(dev, "Failed to get engine clock:
> > %d\n",
> > +				ret);
> 
> Why are you breaking this line?
> 

I will fix this.

> > +
> > +		return ret;
> > +	}
> > +
> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n",
> > +				ret);
> > +
> > +		return ret;
> > +	}
> > +
> 
> You're getting this clock twice, what happened here?
> 
> P.S.: As I explained on the dt-bindings patch, you likely don't even
> need this
>        clock at all.
> 

I will remove this.
For this clock gate, we stiil need to enable it.

I reply in binding patch.

I rename it as pll_gate.

> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n", ret);
> >   
> >   		return ret;
> >   	}
> > @@ -1004,6 +1093,9 @@ static const struct of_device_id
> > mtk_dpi_of_ids[] = {
> >   	{ .compatible = "mediatek,mt8192-dpi",
> >   	  .data = &mt8192_conf,
> >   	},
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = &mt8195_dpintf_conf,
> > +	},
> >   	{ },
> >   };
> >   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > index 3a02fabe1662..dd47dd3f2e4f 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > @@ -40,10 +40,15 @@
> >   #define FAKE_DE_LEVEN			BIT(21)
> >   #define FAKE_DE_RODD			BIT(22)
> >   #define FAKE_DE_REVEN			BIT(23)
> > +#define DPINTF_YUV422_EN		BIT(24)
> > +#define DPINTF_CSC_ENABLE		BIT(26)
> > +#define DPINTF_INPUT_2P_EN		BIT(29)
> >   
> >   #define DPI_OUTPUT_SETTING	0x14
> >   #define CH_SWAP				0
> > +#define DPINTF_CH_SWAP			BIT(1)
> >   #define CH_SWAP_MASK			(0x7 << 0)
> > +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> >   #define SWAP_RGB			0x00
> >   #define SWAP_GBR			0x01
> >   #define SWAP_BRG			0x02
> > @@ -80,8 +85,10 @@
> >   #define DPI_SIZE		0x18
> >   #define HSIZE				0
> >   #define HSIZE_MASK			(0x1FFF << 0)
> > +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
> >   #define VSIZE				16
> >   #define VSIZE_MASK			(0x1FFF << 16)
> > +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
> >   
> >   #define DPI_DDR_SETTING		0x1C
> >   #define DDR_EN				BIT(0)
> > @@ -93,24 +100,30 @@
> >   #define DPI_TGEN_HWIDTH		0x20
> >   #define HPW				0
> >   #define HPW_MASK			(0xFFF << 0)
> > +#define DPINTF_HPW_MASK			(0xFFFF << 0)
> >   
> >   #define DPI_TGEN_HPORCH		0x24
> >   #define HBP				0
> >   #define HBP_MASK			(0xFFF << 0)
> > +#define DPINTF_HBP_MASK			(0xFFFF << 0)
> >   #define HFP				16
> >   #define HFP_MASK			(0xFFF << 16)
> > +#define DPINTF_HFP_MASK			(0xFFFF << 16)
> >   
> >   #define DPI_TGEN_VWIDTH		0x28
> >   #define DPI_TGEN_VPORCH		0x2C
> >   
> >   #define VSYNC_WIDTH_SHIFT		0
> >   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
> >   #define VSYNC_HALF_LINE_SHIFT		16
> >   #define VSYNC_HALF_LINE_MASK		BIT(16)
> >   #define VSYNC_BACK_PORCH_SHIFT		0
> >   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
> >   #define VSYNC_FRONT_PORCH_SHIFT		16
> >   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> > +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
> >   
> >   #define DPI_BG_HCNTL		0x30
> >   #define BG_RIGHT			(0x1FFF << 0)
> > @@ -217,4 +230,26 @@
> >   
> >   #define EDGE_SEL_EN			BIT(5)
> >   #define H_FRE_2N			BIT(25)
> > +
> > +#define RGB_TO_JPEG			0x00
> 
> This is 0x0
> 
> > +#define RGB_TO_FULL709			0x01
> 
> 0x1
> 
> > +#define RGB_TO_BT601			0x02
> 
> 0x2
> 
> ...remove the unnecessary leading zeros, but... you're not ever
> using this set of definitions, so why are you even adding them?
> 

ok, I will remove them.

> > +#define RGB_TO_BT709			0x03
> > +#define JPEG_TO_RGB			0x04
> > +#define FULL709_TO_RGB			0x05
> > +#define BT601_TO_RGB			0x06
> > +#define BT709_TO_RGB			0x07
> > +#define JPEG_TO_BT601			0x08
> > +#define JPEG_TO_BT709			0x09
> > +#define BT601_TO_JPEG			0xA
> > +#define BT709_TO_JPEG			0xB
> > +#define BT709_TO_BT601			0xC
> > +#define BT601_TO_BT709			0xD
> > +#define JPEG_TO_CERGB			0x14
> > +#define FULL709_TO_CERGB		0x15
> > +#define BT601_TO_CERGB			0x16
> > +#define BT709_TO_CERGB			0x17
> > +#define RGB_TO_CERGB			0x1C
> > +#define MATRIX_BIT			BIT(8)
> > +#define EXT_MATRIX_EN			BIT(12)
> >   #endif /* __MTK_DPI_REGS_H */
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 245d0074e12d..3738665a712e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -419,6 +419,11 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >   	[MTK_DISP_WDMA] = "wdma",
> >   	[MTK_DPI] = "dpi",
> >   	[MTK_DSI] = "dsi",
> > +	[MTK_DP_INTF] = "dp-intf",
> > +	[MTK_DISP_PWM] = "pwm",
> > +	[MTK_DISP_MUTEX] = "mutex",
> > +	[MTK_DISP_OD] = "od",
> > +	[MTK_DISP_BLS] = "bls",
> 
> Please keep alphabetic order.
> 

Some of this are redundant, and I will remove them.

> >   };
> >   
> >   struct mtk_ddp_comp_match {
> > @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			
> > 1, &ddp_dpi },
> >   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		
> > 0, &ddp_dsc },
> >   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		
> > 1, &ddp_dsc },
> > +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi
> > },
> > +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi
> > },
> 
> Indentation issue. Fix it.
> 

Some of this are redundant, and I will remove them.

> >   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			
> > 0, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			
> > 1, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			
> > 2, &ddp_dsi },
> > @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node,
> > struct mtk_ddp_comp *comp,
> >   	    type == MTK_DISP_PWM ||
> >   	    type == MTK_DISP_RDMA ||
> >   	    type == MTK_DPI ||
> > +	    type == MTK_DP_INTF ||
> >   	    type == MTK_DSI)
> >   		return 0;
> >   
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index 825d763d2378..c4e683f46a95 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
> >   	MTK_DISP_UFOE,
> >   	MTK_DISP_WDMA,
> >   	MTK_DPI,
> > +	MTK_DP_INTF,
> >   	MTK_DSI,
> >   	MTK_DDP_COMP_TYPE_MAX,
> >   };
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index a2a783fc580e..e25ac61aac08 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -690,6 +690,8 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >   	  .data = (void *)MTK_DPI },
> >   	{ .compatible = "mediatek,mt8183-dpi",
> >   	  .data = (void *)MTK_DPI },
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = (void *)MTK_DP_INTF },
> >   	{ .compatible = "mediatek,mt2701-dsi",
> >   	  .data = (void *)MTK_DSI },
> >   	{ .compatible = "mediatek,mt8173-dsi",
> > @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device
> > *pdev)
> >   		    comp_type == MTK_DISP_OVL_2L ||
> >   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
> >   		    comp_type == MTK_DISP_RDMA ||
> > +		    comp_type == MTK_DSI ||
> >   		    comp_type == MTK_DPI ||
> > -		    comp_type == MTK_DSI) {
> > +		    comp_type == MTK_DP_INTF) {
> 
> These were nice and alphabetically ordered, why are you moving
> MTK_DSI up there?!
> 
>   		    comp_type == MTK_DISP_RDMA ||
> 		    comp_type == MTK_DP_INTF ||
>   		    comp_type == MTK_DPI ||
> 		    comp_type == MTK_DSI) {
> 
> ... that's how it should look like.
> 

Some of this are redundant, and I will remove them.

> >   			dev_info(dev, "Adding component match for
> > %pOF\n",
> >   				 node);
> >   			drm_of_component_match_add(dev, &match,
> > component_compare_of,
> > diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> > b/include/linux/soc/mediatek/mtk-mmsys.h
> > index 3e998bfb795a..e4b84c347201 100644
> > --- a/include/linux/soc/mediatek/mtk-mmsys.h
> > +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> > @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
> >   	DDP_COMPONENT_COLOR0,
> >   	DDP_COMPONENT_COLOR1,
> >   	DDP_COMPONENT_DITHER,
> > -	DDP_COMPONENT_DP_INTF0,
> > -	DDP_COMPONENT_DP_INTF1,
> >   	DDP_COMPONENT_DPI0,
> >   	DDP_COMPONENT_DPI1,
> >   	DDP_COMPONENT_DSC0,
> >   	DDP_COMPONENT_DSC1,
> > +	DDP_COMPONENT_DP_INTF0,
> > +	DDP_COMPONENT_DP_INTF1,
> 
> Why are you moving this?!
> 

I will fix this.

BRs,
Bo-Chen

> >   	DDP_COMPONENT_DSI0,
> >   	DDP_COMPONENT_DSI1,
> >   	DDP_COMPONENT_DSI2,
> 
> 


^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-13  6:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:58 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> 
> Only after finishing the review, I've noticed that I just wrote the
> same things
> that I wrote in my review for version 8... and if I recall correctly,
> this is not
> the first time that something like that happens.
> 
> Please pay attention to what reviewers say, as to not waste anyone's
> time.
> 

Hello Angelo,

I will help to fix these issue in next version.

> 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> > @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   
> >   	vm.pixelclock = pll_rate / factor;
> >   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> > -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> > +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
> 
> The indentation was perfect before that change...
> 
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> > -	else
> > +	} else {
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> > -
> > +	}
> >   
> >   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
> >   
> > @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> >   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> > -	hsync.sync_width = vm.hsync_len;
> > -	hsync.back_porch = vm.hback_porch;
> > -	hsync.front_porch = vm.hfront_porch;
> > +	if (dpi->conf->is_dpintf) {
> > +		hsync.sync_width = vm.hsync_len / 4;
> > +		hsync.back_porch = vm.hback_porch / 4;
> > +		hsync.front_porch = vm.hfront_porch / 4;
> > +	} else {
> > +		hsync.sync_width = vm.hsync_len;
> > +		hsync.back_porch = vm.hback_porch;
> > +		hsync.front_porch = vm.hfront_porch;
> > +	}
> 
> This looks way better:
> 
> 	hsync.sync_width = vm.hsync_len;
> 	hsync.back_porch = vm.hback_porch;
> 	hsync.front_porch = vm.hfront_porch;
> 
> 	/* For DPINTF, we need to divide everything by 4 .. lanes? */
> 	if (dpi->conf->is_dpintf) {
> 		hsync.sync_width /= 4;
> 		hsync.back_porch /= 4;
> 		hsync.front_porch /= 4;
> 	}
> 

ok.

> >   	hsync.shift_half_line = false;
> >   	vsync_lodd.sync_width = vm.vsync_len;
> >   	vsync_lodd.back_porch = vm.vback_porch;
> > @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   	mtk_dpi_config_channel_limit(dpi);
> >   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> >   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> > -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> >   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> > -	mtk_dpi_config_2n_h_fre(dpi);
> > -	mtk_dpi_dual_edge(dpi);
> > -	mtk_dpi_config_disable_edge(dpi);
> > +	if (dpi->conf->is_dpintf) {
> > +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> > +			     DPINTF_INPUT_2P_EN);
> > +	} else {
> > +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> > +		mtk_dpi_config_2n_h_fre(dpi);
> > +		mtk_dpi_dual_edge(dpi);
> > +		mtk_dpi_config_disable_edge(dpi);
> > +	}
> >   	mtk_dpi_sw_reset(dpi, false);
> >   
> > +	mtk_dpi_enable(dpi);
> > +
> >   	return 0;
> >   }
> >   
> > @@ -608,7 +639,6 @@ static u32
> > *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge
> > *bridge,
> >   	u32 *input_fmts;
> >   
> >   	*num_input_fmts = 0;
> > -
> 
> Removing this line is not part of adding dpintf support, so don't do
> that.
> 

ok.

> >   	input_fmts = kcalloc(1, sizeof(*input_fmts),
> >   			     GFP_KERNEL);
> >   	if (!input_fmts)
> > @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct
> > drm_bridge *bridge,
> >   		if (dpi->conf->num_output_fmts)
> >   			out_bus_format = dpi->conf->output_fmts[0];
> >   
> > -	dev_dbg(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > -		bridge_state->input_bus_cfg.format,
> > -		bridge_state->output_bus_cfg.format);
> > +	dev_info(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > +		 bridge_state->input_bus_cfg.format,
> > +		 bridge_state->output_bus_cfg.format);
> 
> This message is not giving any constantly changing information, nor
> any one that
> is interesting for the user: keep this as dev_dbg().
> 

ok.

> >   
> >   	dpi->output_fmt = out_bus_format;
> >   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
> >   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
> >   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> > -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> > +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> > +		dpi->color_format =
> > MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> > +	else
> > +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> >   
> >   	return 0;
> >   }
> > @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge
> > *bridge,
> >   {
> >   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
> >   
> > -	if (mode->clock > dpi->conf->max_clock_khz)
> > +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf-
> > >max_clock_khz)
> >   		return MODE_CLOCK_HIGH;
> >   
> >   	return MODE_OK;
> > @@ -801,6 +834,16 @@ static unsigned int
> > mt8183_calculate_factor(int clock)
> >   		return 2;
> >   }
> >   
> > +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> > +{
> > +	if (clock < 70000)
> 
> is 70000 intentional? Or did you mean 700000?
> 

70000 is correct, the unit for this is KHz.


> > +		return 4;
> > +	else if (clock < 200000)
> > +		return 2;
> > +	else
> > +		return 1;
> > +}
> > +
> >   static const u32 mt8173_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_1X24,
> >   };
> > @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_2X12_BE,
> >   };
> >   
> > +static const u32 mt8195_output_fmts[] = {
> > +	MEDIA_BUS_FMT_RGB888_1X24,
> > +	MEDIA_BUS_FMT_YUV8_1X24,
> > +	MEDIA_BUS_FMT_YUYV8_1X16,
> > +};
> > +
> >   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
> >   	.c_bottom = 0x0010,
> >   	.c_top = 0x0FE0,
> > @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit
> > mtk_dpi_limit = {
> >   	.y_top = 0x0FE0,
> >   };
> >   
> > +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> > +	.c_bottom = 0x0000,
> > +	.c_top = 0xFFF,
> > +	.y_bottom = 0x0000,
> > +	.y_top = 0xFFF,
> > +};
> > +
> >   static const struct mtk_dpi_conf mt8173_conf = {
> >   	.cal_factor = mt8173_calculate_factor,
> >   	.reg_h_fre_con = 0xe0,
> > @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >   	.limit = &mtk_dpi_limit,
> >   };
> >   
> > +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> > +	.cal_factor = mt8195_dpintf_calculate_factor,
> > +	.output_fmts = mt8195_output_fmts,
> > +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> > +	.is_dpintf = true,
> > +	.dimension_mask = DPINTF_HPW_MASK,
> > +	.hvsize_mask = DPINTF_HSIZE_MASK,
> > +	.channel_swap_shift = DPINTF_CH_SWAP,
> > +	.yuv422_en_bit = DPINTF_YUV422_EN,
> > +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> > +	.limit = &mtk_dpintf_limit,
> > +};
> > +
> >   static int mtk_dpi_probe(struct platform_device *pdev)
> >   {
> >   	struct device *dev = &pdev->dev;
> > @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct
> > platform_device *pdev)
> >   	if (IS_ERR(dpi->engine_clk)) {
> >   		ret = PTR_ERR(dpi->engine_clk);
> >   		if (ret != -EPROBE_DEFER)
> > -			dev_err(dev, "Failed to get engine clock:
> > %d\n", ret);
> > +			dev_err(dev, "Failed to get engine clock:
> > %d\n",
> > +				ret);
> 
> Why are you breaking this line?
> 

I will fix this.

> > +
> > +		return ret;
> > +	}
> > +
> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n",
> > +				ret);
> > +
> > +		return ret;
> > +	}
> > +
> 
> You're getting this clock twice, what happened here?
> 
> P.S.: As I explained on the dt-bindings patch, you likely don't even
> need this
>        clock at all.
> 

I will remove this.
For this clock gate, we stiil need to enable it.

I reply in binding patch.

I rename it as pll_gate.

> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n", ret);
> >   
> >   		return ret;
> >   	}
> > @@ -1004,6 +1093,9 @@ static const struct of_device_id
> > mtk_dpi_of_ids[] = {
> >   	{ .compatible = "mediatek,mt8192-dpi",
> >   	  .data = &mt8192_conf,
> >   	},
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = &mt8195_dpintf_conf,
> > +	},
> >   	{ },
> >   };
> >   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > index 3a02fabe1662..dd47dd3f2e4f 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > @@ -40,10 +40,15 @@
> >   #define FAKE_DE_LEVEN			BIT(21)
> >   #define FAKE_DE_RODD			BIT(22)
> >   #define FAKE_DE_REVEN			BIT(23)
> > +#define DPINTF_YUV422_EN		BIT(24)
> > +#define DPINTF_CSC_ENABLE		BIT(26)
> > +#define DPINTF_INPUT_2P_EN		BIT(29)
> >   
> >   #define DPI_OUTPUT_SETTING	0x14
> >   #define CH_SWAP				0
> > +#define DPINTF_CH_SWAP			BIT(1)
> >   #define CH_SWAP_MASK			(0x7 << 0)
> > +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> >   #define SWAP_RGB			0x00
> >   #define SWAP_GBR			0x01
> >   #define SWAP_BRG			0x02
> > @@ -80,8 +85,10 @@
> >   #define DPI_SIZE		0x18
> >   #define HSIZE				0
> >   #define HSIZE_MASK			(0x1FFF << 0)
> > +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
> >   #define VSIZE				16
> >   #define VSIZE_MASK			(0x1FFF << 16)
> > +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
> >   
> >   #define DPI_DDR_SETTING		0x1C
> >   #define DDR_EN				BIT(0)
> > @@ -93,24 +100,30 @@
> >   #define DPI_TGEN_HWIDTH		0x20
> >   #define HPW				0
> >   #define HPW_MASK			(0xFFF << 0)
> > +#define DPINTF_HPW_MASK			(0xFFFF << 0)
> >   
> >   #define DPI_TGEN_HPORCH		0x24
> >   #define HBP				0
> >   #define HBP_MASK			(0xFFF << 0)
> > +#define DPINTF_HBP_MASK			(0xFFFF << 0)
> >   #define HFP				16
> >   #define HFP_MASK			(0xFFF << 16)
> > +#define DPINTF_HFP_MASK			(0xFFFF << 16)
> >   
> >   #define DPI_TGEN_VWIDTH		0x28
> >   #define DPI_TGEN_VPORCH		0x2C
> >   
> >   #define VSYNC_WIDTH_SHIFT		0
> >   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
> >   #define VSYNC_HALF_LINE_SHIFT		16
> >   #define VSYNC_HALF_LINE_MASK		BIT(16)
> >   #define VSYNC_BACK_PORCH_SHIFT		0
> >   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
> >   #define VSYNC_FRONT_PORCH_SHIFT		16
> >   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> > +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
> >   
> >   #define DPI_BG_HCNTL		0x30
> >   #define BG_RIGHT			(0x1FFF << 0)
> > @@ -217,4 +230,26 @@
> >   
> >   #define EDGE_SEL_EN			BIT(5)
> >   #define H_FRE_2N			BIT(25)
> > +
> > +#define RGB_TO_JPEG			0x00
> 
> This is 0x0
> 
> > +#define RGB_TO_FULL709			0x01
> 
> 0x1
> 
> > +#define RGB_TO_BT601			0x02
> 
> 0x2
> 
> ...remove the unnecessary leading zeros, but... you're not ever
> using this set of definitions, so why are you even adding them?
> 

ok, I will remove them.

> > +#define RGB_TO_BT709			0x03
> > +#define JPEG_TO_RGB			0x04
> > +#define FULL709_TO_RGB			0x05
> > +#define BT601_TO_RGB			0x06
> > +#define BT709_TO_RGB			0x07
> > +#define JPEG_TO_BT601			0x08
> > +#define JPEG_TO_BT709			0x09
> > +#define BT601_TO_JPEG			0xA
> > +#define BT709_TO_JPEG			0xB
> > +#define BT709_TO_BT601			0xC
> > +#define BT601_TO_BT709			0xD
> > +#define JPEG_TO_CERGB			0x14
> > +#define FULL709_TO_CERGB		0x15
> > +#define BT601_TO_CERGB			0x16
> > +#define BT709_TO_CERGB			0x17
> > +#define RGB_TO_CERGB			0x1C
> > +#define MATRIX_BIT			BIT(8)
> > +#define EXT_MATRIX_EN			BIT(12)
> >   #endif /* __MTK_DPI_REGS_H */
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 245d0074e12d..3738665a712e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -419,6 +419,11 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >   	[MTK_DISP_WDMA] = "wdma",
> >   	[MTK_DPI] = "dpi",
> >   	[MTK_DSI] = "dsi",
> > +	[MTK_DP_INTF] = "dp-intf",
> > +	[MTK_DISP_PWM] = "pwm",
> > +	[MTK_DISP_MUTEX] = "mutex",
> > +	[MTK_DISP_OD] = "od",
> > +	[MTK_DISP_BLS] = "bls",
> 
> Please keep alphabetic order.
> 

Some of this are redundant, and I will remove them.

> >   };
> >   
> >   struct mtk_ddp_comp_match {
> > @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			
> > 1, &ddp_dpi },
> >   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		
> > 0, &ddp_dsc },
> >   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		
> > 1, &ddp_dsc },
> > +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi
> > },
> > +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi
> > },
> 
> Indentation issue. Fix it.
> 

Some of this are redundant, and I will remove them.

> >   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			
> > 0, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			
> > 1, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			
> > 2, &ddp_dsi },
> > @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node,
> > struct mtk_ddp_comp *comp,
> >   	    type == MTK_DISP_PWM ||
> >   	    type == MTK_DISP_RDMA ||
> >   	    type == MTK_DPI ||
> > +	    type == MTK_DP_INTF ||
> >   	    type == MTK_DSI)
> >   		return 0;
> >   
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index 825d763d2378..c4e683f46a95 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
> >   	MTK_DISP_UFOE,
> >   	MTK_DISP_WDMA,
> >   	MTK_DPI,
> > +	MTK_DP_INTF,
> >   	MTK_DSI,
> >   	MTK_DDP_COMP_TYPE_MAX,
> >   };
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index a2a783fc580e..e25ac61aac08 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -690,6 +690,8 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >   	  .data = (void *)MTK_DPI },
> >   	{ .compatible = "mediatek,mt8183-dpi",
> >   	  .data = (void *)MTK_DPI },
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = (void *)MTK_DP_INTF },
> >   	{ .compatible = "mediatek,mt2701-dsi",
> >   	  .data = (void *)MTK_DSI },
> >   	{ .compatible = "mediatek,mt8173-dsi",
> > @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device
> > *pdev)
> >   		    comp_type == MTK_DISP_OVL_2L ||
> >   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
> >   		    comp_type == MTK_DISP_RDMA ||
> > +		    comp_type == MTK_DSI ||
> >   		    comp_type == MTK_DPI ||
> > -		    comp_type == MTK_DSI) {
> > +		    comp_type == MTK_DP_INTF) {
> 
> These were nice and alphabetically ordered, why are you moving
> MTK_DSI up there?!
> 
>   		    comp_type == MTK_DISP_RDMA ||
> 		    comp_type == MTK_DP_INTF ||
>   		    comp_type == MTK_DPI ||
> 		    comp_type == MTK_DSI) {
> 
> ... that's how it should look like.
> 

Some of this are redundant, and I will remove them.

> >   			dev_info(dev, "Adding component match for
> > %pOF\n",
> >   				 node);
> >   			drm_of_component_match_add(dev, &match,
> > component_compare_of,
> > diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> > b/include/linux/soc/mediatek/mtk-mmsys.h
> > index 3e998bfb795a..e4b84c347201 100644
> > --- a/include/linux/soc/mediatek/mtk-mmsys.h
> > +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> > @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
> >   	DDP_COMPONENT_COLOR0,
> >   	DDP_COMPONENT_COLOR1,
> >   	DDP_COMPONENT_DITHER,
> > -	DDP_COMPONENT_DP_INTF0,
> > -	DDP_COMPONENT_DP_INTF1,
> >   	DDP_COMPONENT_DPI0,
> >   	DDP_COMPONENT_DPI1,
> >   	DDP_COMPONENT_DSC0,
> >   	DDP_COMPONENT_DSC1,
> > +	DDP_COMPONENT_DP_INTF0,
> > +	DDP_COMPONENT_DP_INTF1,
> 
> Why are you moving this?!
> 

I will fix this.

BRs,
Bo-Chen

> >   	DDP_COMPONENT_DSI0,
> >   	DDP_COMPONENT_DSI1,
> >   	DDP_COMPONENT_DSI2,
> 
> 


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-13  6:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:58 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> 
> Only after finishing the review, I've noticed that I just wrote the
> same things
> that I wrote in my review for version 8... and if I recall correctly,
> this is not
> the first time that something like that happens.
> 
> Please pay attention to what reviewers say, as to not waste anyone's
> time.
> 

Hello Angelo,

I will help to fix these issue in next version.

> 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> > @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   
> >   	vm.pixelclock = pll_rate / factor;
> >   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> > -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> > +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
> 
> The indentation was perfect before that change...
> 
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> > -	else
> > +	} else {
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> > -
> > +	}
> >   
> >   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
> >   
> > @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> >   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> > -	hsync.sync_width = vm.hsync_len;
> > -	hsync.back_porch = vm.hback_porch;
> > -	hsync.front_porch = vm.hfront_porch;
> > +	if (dpi->conf->is_dpintf) {
> > +		hsync.sync_width = vm.hsync_len / 4;
> > +		hsync.back_porch = vm.hback_porch / 4;
> > +		hsync.front_porch = vm.hfront_porch / 4;
> > +	} else {
> > +		hsync.sync_width = vm.hsync_len;
> > +		hsync.back_porch = vm.hback_porch;
> > +		hsync.front_porch = vm.hfront_porch;
> > +	}
> 
> This looks way better:
> 
> 	hsync.sync_width = vm.hsync_len;
> 	hsync.back_porch = vm.hback_porch;
> 	hsync.front_porch = vm.hfront_porch;
> 
> 	/* For DPINTF, we need to divide everything by 4 .. lanes? */
> 	if (dpi->conf->is_dpintf) {
> 		hsync.sync_width /= 4;
> 		hsync.back_porch /= 4;
> 		hsync.front_porch /= 4;
> 	}
> 

ok.

> >   	hsync.shift_half_line = false;
> >   	vsync_lodd.sync_width = vm.vsync_len;
> >   	vsync_lodd.back_porch = vm.vback_porch;
> > @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   	mtk_dpi_config_channel_limit(dpi);
> >   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> >   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> > -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> >   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> > -	mtk_dpi_config_2n_h_fre(dpi);
> > -	mtk_dpi_dual_edge(dpi);
> > -	mtk_dpi_config_disable_edge(dpi);
> > +	if (dpi->conf->is_dpintf) {
> > +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> > +			     DPINTF_INPUT_2P_EN);
> > +	} else {
> > +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> > +		mtk_dpi_config_2n_h_fre(dpi);
> > +		mtk_dpi_dual_edge(dpi);
> > +		mtk_dpi_config_disable_edge(dpi);
> > +	}
> >   	mtk_dpi_sw_reset(dpi, false);
> >   
> > +	mtk_dpi_enable(dpi);
> > +
> >   	return 0;
> >   }
> >   
> > @@ -608,7 +639,6 @@ static u32
> > *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge
> > *bridge,
> >   	u32 *input_fmts;
> >   
> >   	*num_input_fmts = 0;
> > -
> 
> Removing this line is not part of adding dpintf support, so don't do
> that.
> 

ok.

> >   	input_fmts = kcalloc(1, sizeof(*input_fmts),
> >   			     GFP_KERNEL);
> >   	if (!input_fmts)
> > @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct
> > drm_bridge *bridge,
> >   		if (dpi->conf->num_output_fmts)
> >   			out_bus_format = dpi->conf->output_fmts[0];
> >   
> > -	dev_dbg(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > -		bridge_state->input_bus_cfg.format,
> > -		bridge_state->output_bus_cfg.format);
> > +	dev_info(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > +		 bridge_state->input_bus_cfg.format,
> > +		 bridge_state->output_bus_cfg.format);
> 
> This message is not giving any constantly changing information, nor
> any one that
> is interesting for the user: keep this as dev_dbg().
> 

ok.

> >   
> >   	dpi->output_fmt = out_bus_format;
> >   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
> >   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
> >   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> > -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> > +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> > +		dpi->color_format =
> > MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> > +	else
> > +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> >   
> >   	return 0;
> >   }
> > @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge
> > *bridge,
> >   {
> >   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
> >   
> > -	if (mode->clock > dpi->conf->max_clock_khz)
> > +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf-
> > >max_clock_khz)
> >   		return MODE_CLOCK_HIGH;
> >   
> >   	return MODE_OK;
> > @@ -801,6 +834,16 @@ static unsigned int
> > mt8183_calculate_factor(int clock)
> >   		return 2;
> >   }
> >   
> > +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> > +{
> > +	if (clock < 70000)
> 
> is 70000 intentional? Or did you mean 700000?
> 

70000 is correct, the unit for this is KHz.


> > +		return 4;
> > +	else if (clock < 200000)
> > +		return 2;
> > +	else
> > +		return 1;
> > +}
> > +
> >   static const u32 mt8173_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_1X24,
> >   };
> > @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_2X12_BE,
> >   };
> >   
> > +static const u32 mt8195_output_fmts[] = {
> > +	MEDIA_BUS_FMT_RGB888_1X24,
> > +	MEDIA_BUS_FMT_YUV8_1X24,
> > +	MEDIA_BUS_FMT_YUYV8_1X16,
> > +};
> > +
> >   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
> >   	.c_bottom = 0x0010,
> >   	.c_top = 0x0FE0,
> > @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit
> > mtk_dpi_limit = {
> >   	.y_top = 0x0FE0,
> >   };
> >   
> > +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> > +	.c_bottom = 0x0000,
> > +	.c_top = 0xFFF,
> > +	.y_bottom = 0x0000,
> > +	.y_top = 0xFFF,
> > +};
> > +
> >   static const struct mtk_dpi_conf mt8173_conf = {
> >   	.cal_factor = mt8173_calculate_factor,
> >   	.reg_h_fre_con = 0xe0,
> > @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >   	.limit = &mtk_dpi_limit,
> >   };
> >   
> > +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> > +	.cal_factor = mt8195_dpintf_calculate_factor,
> > +	.output_fmts = mt8195_output_fmts,
> > +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> > +	.is_dpintf = true,
> > +	.dimension_mask = DPINTF_HPW_MASK,
> > +	.hvsize_mask = DPINTF_HSIZE_MASK,
> > +	.channel_swap_shift = DPINTF_CH_SWAP,
> > +	.yuv422_en_bit = DPINTF_YUV422_EN,
> > +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> > +	.limit = &mtk_dpintf_limit,
> > +};
> > +
> >   static int mtk_dpi_probe(struct platform_device *pdev)
> >   {
> >   	struct device *dev = &pdev->dev;
> > @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct
> > platform_device *pdev)
> >   	if (IS_ERR(dpi->engine_clk)) {
> >   		ret = PTR_ERR(dpi->engine_clk);
> >   		if (ret != -EPROBE_DEFER)
> > -			dev_err(dev, "Failed to get engine clock:
> > %d\n", ret);
> > +			dev_err(dev, "Failed to get engine clock:
> > %d\n",
> > +				ret);
> 
> Why are you breaking this line?
> 

I will fix this.

> > +
> > +		return ret;
> > +	}
> > +
> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n",
> > +				ret);
> > +
> > +		return ret;
> > +	}
> > +
> 
> You're getting this clock twice, what happened here?
> 
> P.S.: As I explained on the dt-bindings patch, you likely don't even
> need this
>        clock at all.
> 

I will remove this.
For this clock gate, we stiil need to enable it.

I reply in binding patch.

I rename it as pll_gate.

> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n", ret);
> >   
> >   		return ret;
> >   	}
> > @@ -1004,6 +1093,9 @@ static const struct of_device_id
> > mtk_dpi_of_ids[] = {
> >   	{ .compatible = "mediatek,mt8192-dpi",
> >   	  .data = &mt8192_conf,
> >   	},
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = &mt8195_dpintf_conf,
> > +	},
> >   	{ },
> >   };
> >   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > index 3a02fabe1662..dd47dd3f2e4f 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > @@ -40,10 +40,15 @@
> >   #define FAKE_DE_LEVEN			BIT(21)
> >   #define FAKE_DE_RODD			BIT(22)
> >   #define FAKE_DE_REVEN			BIT(23)
> > +#define DPINTF_YUV422_EN		BIT(24)
> > +#define DPINTF_CSC_ENABLE		BIT(26)
> > +#define DPINTF_INPUT_2P_EN		BIT(29)
> >   
> >   #define DPI_OUTPUT_SETTING	0x14
> >   #define CH_SWAP				0
> > +#define DPINTF_CH_SWAP			BIT(1)
> >   #define CH_SWAP_MASK			(0x7 << 0)
> > +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> >   #define SWAP_RGB			0x00
> >   #define SWAP_GBR			0x01
> >   #define SWAP_BRG			0x02
> > @@ -80,8 +85,10 @@
> >   #define DPI_SIZE		0x18
> >   #define HSIZE				0
> >   #define HSIZE_MASK			(0x1FFF << 0)
> > +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
> >   #define VSIZE				16
> >   #define VSIZE_MASK			(0x1FFF << 16)
> > +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
> >   
> >   #define DPI_DDR_SETTING		0x1C
> >   #define DDR_EN				BIT(0)
> > @@ -93,24 +100,30 @@
> >   #define DPI_TGEN_HWIDTH		0x20
> >   #define HPW				0
> >   #define HPW_MASK			(0xFFF << 0)
> > +#define DPINTF_HPW_MASK			(0xFFFF << 0)
> >   
> >   #define DPI_TGEN_HPORCH		0x24
> >   #define HBP				0
> >   #define HBP_MASK			(0xFFF << 0)
> > +#define DPINTF_HBP_MASK			(0xFFFF << 0)
> >   #define HFP				16
> >   #define HFP_MASK			(0xFFF << 16)
> > +#define DPINTF_HFP_MASK			(0xFFFF << 16)
> >   
> >   #define DPI_TGEN_VWIDTH		0x28
> >   #define DPI_TGEN_VPORCH		0x2C
> >   
> >   #define VSYNC_WIDTH_SHIFT		0
> >   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
> >   #define VSYNC_HALF_LINE_SHIFT		16
> >   #define VSYNC_HALF_LINE_MASK		BIT(16)
> >   #define VSYNC_BACK_PORCH_SHIFT		0
> >   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
> >   #define VSYNC_FRONT_PORCH_SHIFT		16
> >   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> > +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
> >   
> >   #define DPI_BG_HCNTL		0x30
> >   #define BG_RIGHT			(0x1FFF << 0)
> > @@ -217,4 +230,26 @@
> >   
> >   #define EDGE_SEL_EN			BIT(5)
> >   #define H_FRE_2N			BIT(25)
> > +
> > +#define RGB_TO_JPEG			0x00
> 
> This is 0x0
> 
> > +#define RGB_TO_FULL709			0x01
> 
> 0x1
> 
> > +#define RGB_TO_BT601			0x02
> 
> 0x2
> 
> ...remove the unnecessary leading zeros, but... you're not ever
> using this set of definitions, so why are you even adding them?
> 

ok, I will remove them.

> > +#define RGB_TO_BT709			0x03
> > +#define JPEG_TO_RGB			0x04
> > +#define FULL709_TO_RGB			0x05
> > +#define BT601_TO_RGB			0x06
> > +#define BT709_TO_RGB			0x07
> > +#define JPEG_TO_BT601			0x08
> > +#define JPEG_TO_BT709			0x09
> > +#define BT601_TO_JPEG			0xA
> > +#define BT709_TO_JPEG			0xB
> > +#define BT709_TO_BT601			0xC
> > +#define BT601_TO_BT709			0xD
> > +#define JPEG_TO_CERGB			0x14
> > +#define FULL709_TO_CERGB		0x15
> > +#define BT601_TO_CERGB			0x16
> > +#define BT709_TO_CERGB			0x17
> > +#define RGB_TO_CERGB			0x1C
> > +#define MATRIX_BIT			BIT(8)
> > +#define EXT_MATRIX_EN			BIT(12)
> >   #endif /* __MTK_DPI_REGS_H */
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 245d0074e12d..3738665a712e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -419,6 +419,11 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >   	[MTK_DISP_WDMA] = "wdma",
> >   	[MTK_DPI] = "dpi",
> >   	[MTK_DSI] = "dsi",
> > +	[MTK_DP_INTF] = "dp-intf",
> > +	[MTK_DISP_PWM] = "pwm",
> > +	[MTK_DISP_MUTEX] = "mutex",
> > +	[MTK_DISP_OD] = "od",
> > +	[MTK_DISP_BLS] = "bls",
> 
> Please keep alphabetic order.
> 

Some of this are redundant, and I will remove them.

> >   };
> >   
> >   struct mtk_ddp_comp_match {
> > @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			
> > 1, &ddp_dpi },
> >   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		
> > 0, &ddp_dsc },
> >   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		
> > 1, &ddp_dsc },
> > +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi
> > },
> > +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi
> > },
> 
> Indentation issue. Fix it.
> 

Some of this are redundant, and I will remove them.

> >   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			
> > 0, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			
> > 1, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			
> > 2, &ddp_dsi },
> > @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node,
> > struct mtk_ddp_comp *comp,
> >   	    type == MTK_DISP_PWM ||
> >   	    type == MTK_DISP_RDMA ||
> >   	    type == MTK_DPI ||
> > +	    type == MTK_DP_INTF ||
> >   	    type == MTK_DSI)
> >   		return 0;
> >   
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index 825d763d2378..c4e683f46a95 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
> >   	MTK_DISP_UFOE,
> >   	MTK_DISP_WDMA,
> >   	MTK_DPI,
> > +	MTK_DP_INTF,
> >   	MTK_DSI,
> >   	MTK_DDP_COMP_TYPE_MAX,
> >   };
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index a2a783fc580e..e25ac61aac08 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -690,6 +690,8 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >   	  .data = (void *)MTK_DPI },
> >   	{ .compatible = "mediatek,mt8183-dpi",
> >   	  .data = (void *)MTK_DPI },
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = (void *)MTK_DP_INTF },
> >   	{ .compatible = "mediatek,mt2701-dsi",
> >   	  .data = (void *)MTK_DSI },
> >   	{ .compatible = "mediatek,mt8173-dsi",
> > @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device
> > *pdev)
> >   		    comp_type == MTK_DISP_OVL_2L ||
> >   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
> >   		    comp_type == MTK_DISP_RDMA ||
> > +		    comp_type == MTK_DSI ||
> >   		    comp_type == MTK_DPI ||
> > -		    comp_type == MTK_DSI) {
> > +		    comp_type == MTK_DP_INTF) {
> 
> These were nice and alphabetically ordered, why are you moving
> MTK_DSI up there?!
> 
>   		    comp_type == MTK_DISP_RDMA ||
> 		    comp_type == MTK_DP_INTF ||
>   		    comp_type == MTK_DPI ||
> 		    comp_type == MTK_DSI) {
> 
> ... that's how it should look like.
> 

Some of this are redundant, and I will remove them.

> >   			dev_info(dev, "Adding component match for
> > %pOF\n",
> >   				 node);
> >   			drm_of_component_match_add(dev, &match,
> > component_compare_of,
> > diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> > b/include/linux/soc/mediatek/mtk-mmsys.h
> > index 3e998bfb795a..e4b84c347201 100644
> > --- a/include/linux/soc/mediatek/mtk-mmsys.h
> > +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> > @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
> >   	DDP_COMPONENT_COLOR0,
> >   	DDP_COMPONENT_COLOR1,
> >   	DDP_COMPONENT_DITHER,
> > -	DDP_COMPONENT_DP_INTF0,
> > -	DDP_COMPONENT_DP_INTF1,
> >   	DDP_COMPONENT_DPI0,
> >   	DDP_COMPONENT_DPI1,
> >   	DDP_COMPONENT_DSC0,
> >   	DDP_COMPONENT_DSC1,
> > +	DDP_COMPONENT_DP_INTF0,
> > +	DDP_COMPONENT_DP_INTF1,
> 
> Why are you moving this?!
> 

I will fix this.

BRs,
Bo-Chen

> >   	DDP_COMPONENT_DSI0,
> >   	DDP_COMPONENT_DSI1,
> >   	DDP_COMPONENT_DSI2,
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 450+ messages in thread

* Re: [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
@ 2022-06-13  6:10       ` Rex-BC Chen
  0 siblings, 0 replies; 450+ messages in thread
From: Rex-BC Chen @ 2022-06-13  6:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Guillaume Ranquet, Chun-Kuang Hu,
	Philipp Zabel, David Airlie, Daniel Vetter, Rob Herring,
	Krzysztof Kozlowski, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Matthias Brugger, Chunfeng Yun,
	Kishon Vijay Abraham I, Vinod Koul, Helge Deller, CK Hu,
	Jitao shi
  Cc: Markus Schneider-Pargmann, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, linux-fbdev

On Wed, 2022-05-25 at 14:58 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/05/22 12:47, Guillaume Ranquet ha scritto:
> > 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 <jason-jh.lin@mediatek.com>.
> > 
> 
> Only after finishing the review, I've noticed that I just wrote the
> same things
> that I wrote in my review for version 8... and if I recall correctly,
> this is not
> the first time that something like that happens.
> 
> Please pay attention to what reviewers say, as to not waste anyone's
> time.
> 

Hello Angelo,

I will help to fix these issue in next version.

> 
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dpi.c          | 126
> > +++++++++++++++++---
> >   drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  35 ++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 ++
> >   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      |   4 +-
> >   6 files changed, 159 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index eb969c5c5c2e..763bfb700135 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,7 @@ struct mtk_dpi {
> >   	void __iomem *regs;
> >   	struct device *dev;
> >   	struct clk *engine_clk;
> > +	struct clk *dpi_ck_cg;
> >   	struct clk *pixel_clk;
> >   	struct clk *tvd_clk;
> >   	int irq;
> > @@ -126,6 +127,7 @@ struct mtk_dpi_conf {
> >   	const u32 *output_fmts;
> >   	u32 num_output_fmts;
> >   	bool is_ck_de_pol;
> > +	bool is_dpintf;
> >   	bool swap_input_support;
> >   	/* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
> > (no shift) */
> >   	u32 dimension_mask;
> > @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi
> > *dpi)
> >   	mtk_dpi_disable(dpi);
> >   	clk_disable_unprepare(dpi->pixel_clk);
> >   	clk_disable_unprepare(dpi->engine_clk);
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +	clk_disable_unprepare(dpi->tvd_clk);
> >   }
> >   
> >   static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> > @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	if (++dpi->refcount != 1)
> >   		return 0;
> >   
> > +	ret = clk_prepare_enable(dpi->tvd_clk);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n",
> > ret);
> > +		goto err_pixel;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->engine_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable engine clock:
> > %d\n", ret);
> >   		goto err_refcount;
> >   	}
> >   
> > +	ret = clk_prepare_enable(dpi->dpi_ck_cg);
> > +	if (ret) {
> > +		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock:
> > %d\n", ret);
> > +		goto err_ck_cg;
> > +	}
> > +
> >   	ret = clk_prepare_enable(dpi->pixel_clk);
> >   	if (ret) {
> >   		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n",
> > ret);
> > @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi
> > *dpi)
> >   	return 0;
> >   
> >   err_pixel:
> > +	clk_disable_unprepare(dpi->dpi_ck_cg);
> > +err_ck_cg:
> >   	clk_disable_unprepare(dpi->engine_clk);
> >   err_refcount:
> >   	dpi->refcount--;
> > @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   
> >   	vm.pixelclock = pll_rate / factor;
> >   	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
> > -	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
> > +		 (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
> 
> The indentation was perfect before that change...
> 
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
> > -	else
> > +	} else {
> >   		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
> > -
> > +	}
> >   
> >   	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
> >   
> > @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> >   	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
> >   			    MTK_DPI_POLARITY_FALLING :
> > MTK_DPI_POLARITY_RISING;
> > -	hsync.sync_width = vm.hsync_len;
> > -	hsync.back_porch = vm.hback_porch;
> > -	hsync.front_porch = vm.hfront_porch;
> > +	if (dpi->conf->is_dpintf) {
> > +		hsync.sync_width = vm.hsync_len / 4;
> > +		hsync.back_porch = vm.hback_porch / 4;
> > +		hsync.front_porch = vm.hfront_porch / 4;
> > +	} else {
> > +		hsync.sync_width = vm.hsync_len;
> > +		hsync.back_porch = vm.hback_porch;
> > +		hsync.front_porch = vm.hfront_porch;
> > +	}
> 
> This looks way better:
> 
> 	hsync.sync_width = vm.hsync_len;
> 	hsync.back_porch = vm.hback_porch;
> 	hsync.front_porch = vm.hfront_porch;
> 
> 	/* For DPINTF, we need to divide everything by 4 .. lanes? */
> 	if (dpi->conf->is_dpintf) {
> 		hsync.sync_width /= 4;
> 		hsync.back_porch /= 4;
> 		hsync.front_porch /= 4;
> 	}
> 

ok.

> >   	hsync.shift_half_line = false;
> >   	vsync_lodd.sync_width = vm.vsync_len;
> >   	vsync_lodd.back_porch = vm.vback_porch;
> > @@ -559,13 +583,20 @@ static int mtk_dpi_set_display_mode(struct
> > mtk_dpi *dpi,
> >   	mtk_dpi_config_channel_limit(dpi);
> >   	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> >   	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> > -	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> >   	mtk_dpi_config_color_format(dpi, dpi->color_format);
> > -	mtk_dpi_config_2n_h_fre(dpi);
> > -	mtk_dpi_dual_edge(dpi);
> > -	mtk_dpi_config_disable_edge(dpi);
> > +	if (dpi->conf->is_dpintf) {
> > +		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
> > +			     DPINTF_INPUT_2P_EN);
> > +	} else {
> > +		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> > +		mtk_dpi_config_2n_h_fre(dpi);
> > +		mtk_dpi_dual_edge(dpi);
> > +		mtk_dpi_config_disable_edge(dpi);
> > +	}
> >   	mtk_dpi_sw_reset(dpi, false);
> >   
> > +	mtk_dpi_enable(dpi);
> > +
> >   	return 0;
> >   }
> >   
> > @@ -608,7 +639,6 @@ static u32
> > *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge
> > *bridge,
> >   	u32 *input_fmts;
> >   
> >   	*num_input_fmts = 0;
> > -
> 
> Removing this line is not part of adding dpintf support, so don't do
> that.
> 

ok.

> >   	input_fmts = kcalloc(1, sizeof(*input_fmts),
> >   			     GFP_KERNEL);
> >   	if (!input_fmts)
> > @@ -634,15 +664,18 @@ static int mtk_dpi_bridge_atomic_check(struct
> > drm_bridge *bridge,
> >   		if (dpi->conf->num_output_fmts)
> >   			out_bus_format = dpi->conf->output_fmts[0];
> >   
> > -	dev_dbg(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > -		bridge_state->input_bus_cfg.format,
> > -		bridge_state->output_bus_cfg.format);
> > +	dev_info(dpi->dev, "input format 0x%04x, output format
> > 0x%04x\n",
> > +		 bridge_state->input_bus_cfg.format,
> > +		 bridge_state->output_bus_cfg.format);
> 
> This message is not giving any constantly changing information, nor
> any one that
> is interesting for the user: keep this as dev_dbg().
> 

ok.

> >   
> >   	dpi->output_fmt = out_bus_format;
> >   	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
> >   	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
> >   	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
> > -	dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> > +	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
> > +		dpi->color_format =
> > MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL;
> > +	else
> > +		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
> >   
> >   	return 0;
> >   }
> > @@ -687,7 +720,7 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge
> > *bridge,
> >   {
> >   	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
> >   
> > -	if (mode->clock > dpi->conf->max_clock_khz)
> > +	if (dpi->conf->max_clock_khz && mode->clock > dpi->conf-
> > >max_clock_khz)
> >   		return MODE_CLOCK_HIGH;
> >   
> >   	return MODE_OK;
> > @@ -801,6 +834,16 @@ static unsigned int
> > mt8183_calculate_factor(int clock)
> >   		return 2;
> >   }
> >   
> > +static unsigned int mt8195_dpintf_calculate_factor(int clock)
> > +{
> > +	if (clock < 70000)
> 
> is 70000 intentional? Or did you mean 700000?
> 

70000 is correct, the unit for this is KHz.


> > +		return 4;
> > +	else if (clock < 200000)
> > +		return 2;
> > +	else
> > +		return 1;
> > +}
> > +
> >   static const u32 mt8173_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_1X24,
> >   };
> > @@ -810,6 +853,12 @@ static const u32 mt8183_output_fmts[] = {
> >   	MEDIA_BUS_FMT_RGB888_2X12_BE,
> >   };
> >   
> > +static const u32 mt8195_output_fmts[] = {
> > +	MEDIA_BUS_FMT_RGB888_1X24,
> > +	MEDIA_BUS_FMT_YUV8_1X24,
> > +	MEDIA_BUS_FMT_YUYV8_1X16,
> > +};
> > +
> >   static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
> >   	.c_bottom = 0x0010,
> >   	.c_top = 0x0FE0,
> > @@ -817,6 +866,13 @@ static const struct mtk_dpi_yc_limit
> > mtk_dpi_limit = {
> >   	.y_top = 0x0FE0,
> >   };
> >   
> > +static const struct mtk_dpi_yc_limit mtk_dpintf_limit = {
> > +	.c_bottom = 0x0000,
> > +	.c_top = 0xFFF,
> > +	.y_bottom = 0x0000,
> > +	.y_top = 0xFFF,
> > +};
> > +
> >   static const struct mtk_dpi_conf mt8173_conf = {
> >   	.cal_factor = mt8173_calculate_factor,
> >   	.reg_h_fre_con = 0xe0,
> > @@ -882,6 +938,19 @@ static const struct mtk_dpi_conf mt8192_conf =
> > {
> >   	.limit = &mtk_dpi_limit,
> >   };
> >   
> > +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> > +	.cal_factor = mt8195_dpintf_calculate_factor,
> > +	.output_fmts = mt8195_output_fmts,
> > +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> > +	.is_dpintf = true,
> > +	.dimension_mask = DPINTF_HPW_MASK,
> > +	.hvsize_mask = DPINTF_HSIZE_MASK,
> > +	.channel_swap_shift = DPINTF_CH_SWAP,
> > +	.yuv422_en_bit = DPINTF_YUV422_EN,
> > +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> > +	.limit = &mtk_dpintf_limit,
> > +};
> > +
> >   static int mtk_dpi_probe(struct platform_device *pdev)
> >   {
> >   	struct device *dev = &pdev->dev;
> > @@ -929,7 +998,27 @@ static int mtk_dpi_probe(struct
> > platform_device *pdev)
> >   	if (IS_ERR(dpi->engine_clk)) {
> >   		ret = PTR_ERR(dpi->engine_clk);
> >   		if (ret != -EPROBE_DEFER)
> > -			dev_err(dev, "Failed to get engine clock:
> > %d\n", ret);
> > +			dev_err(dev, "Failed to get engine clock:
> > %d\n",
> > +				ret);
> 
> Why are you breaking this line?
> 

I will fix this.

> > +
> > +		return ret;
> > +	}
> > +
> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n",
> > +				ret);
> > +
> > +		return ret;
> > +	}
> > +
> 
> You're getting this clock twice, what happened here?
> 
> P.S.: As I explained on the dt-bindings patch, you likely don't even
> need this
>        clock at all.
> 

I will remove this.
For this clock gate, we stiil need to enable it.

I reply in binding patch.

I rename it as pll_gate.

> > +	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
> > +	if (IS_ERR(dpi->dpi_ck_cg)) {
> > +		ret = PTR_ERR(dpi->dpi_ck_cg);
> > +		if (ret != -EPROBE_DEFER)
> > +			dev_err(dev, "Failed to get dpi ck cg clock:
> > %d\n", ret);
> >   
> >   		return ret;
> >   	}
> > @@ -1004,6 +1093,9 @@ static const struct of_device_id
> > mtk_dpi_of_ids[] = {
> >   	{ .compatible = "mediatek,mt8192-dpi",
> >   	  .data = &mt8192_conf,
> >   	},
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = &mt8195_dpintf_conf,
> > +	},
> >   	{ },
> >   };
> >   MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > index 3a02fabe1662..dd47dd3f2e4f 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> > @@ -40,10 +40,15 @@
> >   #define FAKE_DE_LEVEN			BIT(21)
> >   #define FAKE_DE_RODD			BIT(22)
> >   #define FAKE_DE_REVEN			BIT(23)
> > +#define DPINTF_YUV422_EN		BIT(24)
> > +#define DPINTF_CSC_ENABLE		BIT(26)
> > +#define DPINTF_INPUT_2P_EN		BIT(29)
> >   
> >   #define DPI_OUTPUT_SETTING	0x14
> >   #define CH_SWAP				0
> > +#define DPINTF_CH_SWAP			BIT(1)
> >   #define CH_SWAP_MASK			(0x7 << 0)
> > +#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
> >   #define SWAP_RGB			0x00
> >   #define SWAP_GBR			0x01
> >   #define SWAP_BRG			0x02
> > @@ -80,8 +85,10 @@
> >   #define DPI_SIZE		0x18
> >   #define HSIZE				0
> >   #define HSIZE_MASK			(0x1FFF << 0)
> > +#define DPINTF_HSIZE_MASK		(0xFFFF << 0)
> >   #define VSIZE				16
> >   #define VSIZE_MASK			(0x1FFF << 16)
> > +#define DPINTF_VSIZE_MASK		(0xFFFF << 16)
> >   
> >   #define DPI_DDR_SETTING		0x1C
> >   #define DDR_EN				BIT(0)
> > @@ -93,24 +100,30 @@
> >   #define DPI_TGEN_HWIDTH		0x20
> >   #define HPW				0
> >   #define HPW_MASK			(0xFFF << 0)
> > +#define DPINTF_HPW_MASK			(0xFFFF << 0)
> >   
> >   #define DPI_TGEN_HPORCH		0x24
> >   #define HBP				0
> >   #define HBP_MASK			(0xFFF << 0)
> > +#define DPINTF_HBP_MASK			(0xFFFF << 0)
> >   #define HFP				16
> >   #define HFP_MASK			(0xFFF << 16)
> > +#define DPINTF_HFP_MASK			(0xFFFF << 16)
> >   
> >   #define DPI_TGEN_VWIDTH		0x28
> >   #define DPI_TGEN_VPORCH		0x2C
> >   
> >   #define VSYNC_WIDTH_SHIFT		0
> >   #define VSYNC_WIDTH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
> >   #define VSYNC_HALF_LINE_SHIFT		16
> >   #define VSYNC_HALF_LINE_MASK		BIT(16)
> >   #define VSYNC_BACK_PORCH_SHIFT		0
> >   #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
> > +#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
> >   #define VSYNC_FRONT_PORCH_SHIFT		16
> >   #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
> > +#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
> >   
> >   #define DPI_BG_HCNTL		0x30
> >   #define BG_RIGHT			(0x1FFF << 0)
> > @@ -217,4 +230,26 @@
> >   
> >   #define EDGE_SEL_EN			BIT(5)
> >   #define H_FRE_2N			BIT(25)
> > +
> > +#define RGB_TO_JPEG			0x00
> 
> This is 0x0
> 
> > +#define RGB_TO_FULL709			0x01
> 
> 0x1
> 
> > +#define RGB_TO_BT601			0x02
> 
> 0x2
> 
> ...remove the unnecessary leading zeros, but... you're not ever
> using this set of definitions, so why are you even adding them?
> 

ok, I will remove them.

> > +#define RGB_TO_BT709			0x03
> > +#define JPEG_TO_RGB			0x04
> > +#define FULL709_TO_RGB			0x05
> > +#define BT601_TO_RGB			0x06
> > +#define BT709_TO_RGB			0x07
> > +#define JPEG_TO_BT601			0x08
> > +#define JPEG_TO_BT709			0x09
> > +#define BT601_TO_JPEG			0xA
> > +#define BT709_TO_JPEG			0xB
> > +#define BT709_TO_BT601			0xC
> > +#define BT601_TO_BT709			0xD
> > +#define JPEG_TO_CERGB			0x14
> > +#define FULL709_TO_CERGB		0x15
> > +#define BT601_TO_CERGB			0x16
> > +#define BT709_TO_CERGB			0x17
> > +#define RGB_TO_CERGB			0x1C
> > +#define MATRIX_BIT			BIT(8)
> > +#define EXT_MATRIX_EN			BIT(12)
> >   #endif /* __MTK_DPI_REGS_H */
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 245d0074e12d..3738665a712e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -419,6 +419,11 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >   	[MTK_DISP_WDMA] = "wdma",
> >   	[MTK_DPI] = "dpi",
> >   	[MTK_DSI] = "dsi",
> > +	[MTK_DP_INTF] = "dp-intf",
> > +	[MTK_DISP_PWM] = "pwm",
> > +	[MTK_DISP_MUTEX] = "mutex",
> > +	[MTK_DISP_OD] = "od",
> > +	[MTK_DISP_BLS] = "bls",
> 
> Please keep alphabetic order.
> 

Some of this are redundant, and I will remove them.

> >   };
> >   
> >   struct mtk_ddp_comp_match {
> > @@ -439,6 +444,8 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >   	[DDP_COMPONENT_DPI1]		= { MTK_DPI,			
> > 1, &ddp_dpi },
> >   	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		
> > 0, &ddp_dsc },
> >   	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		
> > 1, &ddp_dsc },
> > +	[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,	0, &ddp_dpi
> > },
> > +	[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,	1, &ddp_dpi
> > },
> 
> Indentation issue. Fix it.
> 

Some of this are redundant, and I will remove them.

> >   	[DDP_COMPONENT_DSI0]		= { MTK_DSI,			
> > 0, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			
> > 1, &ddp_dsi },
> >   	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			
> > 2, &ddp_dsi },
> > @@ -565,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node,
> > struct mtk_ddp_comp *comp,
> >   	    type == MTK_DISP_PWM ||
> >   	    type == MTK_DISP_RDMA ||
> >   	    type == MTK_DPI ||
> > +	    type == MTK_DP_INTF ||
> >   	    type == MTK_DSI)
> >   		return 0;
> >   
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index 825d763d2378..c4e683f46a95 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -37,6 +37,7 @@ enum mtk_ddp_comp_type {
> >   	MTK_DISP_UFOE,
> >   	MTK_DISP_WDMA,
> >   	MTK_DPI,
> > +	MTK_DP_INTF,
> >   	MTK_DSI,
> >   	MTK_DDP_COMP_TYPE_MAX,
> >   };
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index a2a783fc580e..e25ac61aac08 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -690,6 +690,8 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >   	  .data = (void *)MTK_DPI },
> >   	{ .compatible = "mediatek,mt8183-dpi",
> >   	  .data = (void *)MTK_DPI },
> > +	{ .compatible = "mediatek,mt8195-dpintf",
> > +	  .data = (void *)MTK_DP_INTF },
> >   	{ .compatible = "mediatek,mt2701-dsi",
> >   	  .data = (void *)MTK_DSI },
> >   	{ .compatible = "mediatek,mt8173-dsi",
> > @@ -801,8 +803,9 @@ static int mtk_drm_probe(struct platform_device
> > *pdev)
> >   		    comp_type == MTK_DISP_OVL_2L ||
> >   		    comp_type == MTK_DISP_OVL_ADAPTOR ||
> >   		    comp_type == MTK_DISP_RDMA ||
> > +		    comp_type == MTK_DSI ||
> >   		    comp_type == MTK_DPI ||
> > -		    comp_type == MTK_DSI) {
> > +		    comp_type == MTK_DP_INTF) {
> 
> These were nice and alphabetically ordered, why are you moving
> MTK_DSI up there?!
> 
>   		    comp_type == MTK_DISP_RDMA ||
> 		    comp_type == MTK_DP_INTF ||
>   		    comp_type == MTK_DPI ||
> 		    comp_type == MTK_DSI) {
> 
> ... that's how it should look like.
> 

Some of this are redundant, and I will remove them.

> >   			dev_info(dev, "Adding component match for
> > %pOF\n",
> >   				 node);
> >   			drm_of_component_match_add(dev, &match,
> > component_compare_of,
> > diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> > b/include/linux/soc/mediatek/mtk-mmsys.h
> > index 3e998bfb795a..e4b84c347201 100644
> > --- a/include/linux/soc/mediatek/mtk-mmsys.h
> > +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> > @@ -21,12 +21,12 @@ enum mtk_ddp_comp_id {
> >   	DDP_COMPONENT_COLOR0,
> >   	DDP_COMPONENT_COLOR1,
> >   	DDP_COMPONENT_DITHER,
> > -	DDP_COMPONENT_DP_INTF0,
> > -	DDP_COMPONENT_DP_INTF1,
> >   	DDP_COMPONENT_DPI0,
> >   	DDP_COMPONENT_DPI1,
> >   	DDP_COMPONENT_DSC0,
> >   	DDP_COMPONENT_DSC1,
> > +	DDP_COMPONENT_DP_INTF0,
> > +	DDP_COMPONENT_DP_INTF1,
> 
> Why are you moving this?!
> 

I will fix this.

BRs,
Bo-Chen

> >   	DDP_COMPONENT_DSI0,
> >   	DDP_COMPONENT_DSI1,
> >   	DDP_COMPONENT_DSI2,
> 
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 450+ messages in thread

end of thread, other threads:[~2022-06-13  6:15 UTC | newest]

Thread overview: 450+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-23 10:47 [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver Guillaume Ranquet
2022-05-23 10:47 ` Guillaume Ranquet
2022-05-23 10:47 ` Guillaume Ranquet
2022-05-23 10:47 ` Guillaume Ranquet
2022-05-23 10:47 ` Guillaume Ranquet
2022-05-23 10:47 ` [PATCH v10 01/21] dt-bindings: mediatek,dpi: Add DPINTF compatible Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 12:33   ` Rob Herring
2022-05-23 12:33     ` [PATCH v10 01/21] dt-bindings: mediatek, dpi: " Rob Herring
2022-05-23 12:33     ` Rob Herring
2022-05-23 12:33     ` Rob Herring
2022-05-23 12:33     ` Rob Herring
2022-05-24  3:29   ` [PATCH v10 01/21] dt-bindings: mediatek,dpi: " Chunfeng Yun
2022-05-24  3:29     ` Chunfeng Yun
2022-05-24  3:29     ` Chunfeng Yun
2022-05-24  3:29     ` Chunfeng Yun
2022-05-24  3:29     ` Chunfeng Yun
2022-05-25 11:55   ` AngeloGioacchino Del Regno
2022-05-25 11:55     ` AngeloGioacchino Del Regno
2022-05-25 11:55     ` AngeloGioacchino Del Regno
2022-05-25 11:55     ` AngeloGioacchino Del Regno
2022-05-25 11:55     ` AngeloGioacchino Del Regno
2022-06-07  2:31     ` Rex-BC Chen
2022-06-07  2:31       ` Rex-BC Chen
2022-06-07  2:31       ` Rex-BC Chen
2022-06-07  2:31       ` Rex-BC Chen
2022-06-07  2:31       ` Rex-BC Chen
2022-05-25 12:49   ` Maxime Ripard
2022-05-25 12:49     ` Maxime Ripard
2022-05-25 12:49     ` Maxime Ripard
2022-05-25 12:49     ` Maxime Ripard
2022-05-25 12:49     ` Maxime Ripard
2022-06-07  2:35     ` Rex-BC Chen
2022-06-07  2:35       ` Rex-BC Chen
2022-06-07  2:35       ` Rex-BC Chen
2022-06-07  2:35       ` Rex-BC Chen
2022-06-07  2:35       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 02/21] dt-bindings: mediatek,dp: Add Display Port binding Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-24  3:35   ` Chunfeng Yun
2022-05-24  3:35     ` Chunfeng Yun
2022-05-24  3:35     ` Chunfeng Yun
2022-05-24  3:35     ` Chunfeng Yun
2022-05-24  3:35     ` Chunfeng Yun
2022-06-10  2:27     ` Rex-BC Chen
2022-06-10  2:27       ` Rex-BC Chen
2022-06-10  2:27       ` Rex-BC Chen
2022-06-10  2:27       ` Rex-BC Chen
2022-06-10  2:27       ` Rex-BC Chen
2022-05-25 15:30   ` AngeloGioacchino Del Regno
2022-05-25 15:30     ` AngeloGioacchino Del Regno
2022-05-25 15:30     ` AngeloGioacchino Del Regno
2022-05-25 15:30     ` AngeloGioacchino Del Regno
2022-05-25 15:30     ` AngeloGioacchino Del Regno
2022-06-10  2:29     ` Rex-BC Chen
2022-06-10  2:29       ` Rex-BC Chen
2022-06-10  2:29       ` Rex-BC Chen
2022-06-10  2:29       ` Rex-BC Chen
2022-06-10  2:29       ` Rex-BC Chen
2022-06-02 13:20   ` Rob Herring
2022-06-02 13:20     ` Rob Herring
2022-06-02 13:20     ` Rob Herring
2022-06-02 13:20     ` Rob Herring
2022-06-02 13:20     ` Rob Herring
2022-05-23 10:47 ` [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:57   ` Matthias Brugger
2022-05-23 10:57     ` Matthias Brugger
2022-05-23 10:57     ` Matthias Brugger
2022-05-23 10:57     ` Matthias Brugger
2022-05-23 10:57     ` Matthias Brugger
2022-06-07  2:44     ` Rex-BC Chen
2022-06-07  2:44       ` Rex-BC Chen
2022-06-07  2:44       ` Rex-BC Chen
2022-06-07  2:44       ` Rex-BC Chen
2022-06-07  2:44       ` Rex-BC Chen
2022-05-25 12:01   ` AngeloGioacchino Del Regno
2022-05-25 12:01     ` AngeloGioacchino Del Regno
2022-05-25 12:01     ` AngeloGioacchino Del Regno
2022-05-25 12:01     ` AngeloGioacchino Del Regno
2022-05-25 12:01     ` AngeloGioacchino Del Regno
2022-06-07  2:45     ` Rex-BC Chen
2022-06-07  2:45       ` Rex-BC Chen
2022-06-07  2:45       ` Rex-BC Chen
2022-06-07  2:45       ` Rex-BC Chen
2022-06-07  2:45       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 04/21] drm/edid: Add cea_sad helpers for freq/length Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-25 12:26   ` AngeloGioacchino Del Regno
2022-05-25 12:26     ` AngeloGioacchino Del Regno
2022-05-25 12:26     ` AngeloGioacchino Del Regno
2022-05-25 12:26     ` AngeloGioacchino Del Regno
2022-05-25 12:26     ` AngeloGioacchino Del Regno
2022-06-10  6:50     ` Rex-BC Chen
2022-06-10  6:50       ` Rex-BC Chen
2022-06-10  6:50       ` Rex-BC Chen
2022-06-10  6:50       ` Rex-BC Chen
2022-06-10  6:50       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 05/21] video/hdmi: Add audio_infoframe packing for DP Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-25 12:32   ` AngeloGioacchino Del Regno
2022-05-25 12:32     ` AngeloGioacchino Del Regno
2022-05-25 12:32     ` AngeloGioacchino Del Regno
2022-05-25 12:32     ` AngeloGioacchino Del Regno
2022-05-25 12:32     ` AngeloGioacchino Del Regno
2022-06-07  3:10     ` Rex-BC Chen
2022-06-07  3:10       ` Rex-BC Chen
2022-06-07  3:10       ` Rex-BC Chen
2022-06-07  3:10       ` Rex-BC Chen
2022-06-07  3:10       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 06/21] drm/mediatek: dpi: move dpi limits to SoC config Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47 ` [PATCH v10 07/21] drm/mediatek: dpi: implement a CK/DE pol toggle in " Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-30  7:44   ` CK Hu
2022-05-30  7:44     ` CK Hu
2022-05-30  7:44     ` CK Hu
2022-05-30  7:44     ` CK Hu
2022-05-30  7:44     ` CK Hu
2022-06-07  2:54     ` Rex-BC Chen
2022-06-07  2:54       ` Rex-BC Chen
2022-06-07  2:54       ` Rex-BC Chen
2022-06-07  2:54       ` Rex-BC Chen
2022-06-07  2:54       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input " Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-30  7:50   ` CK Hu
2022-05-30  7:50     ` CK Hu
2022-05-30  7:50     ` CK Hu
2022-05-30  7:50     ` CK Hu
2022-05-30  7:50     ` CK Hu
2022-06-13  3:12     ` Rex-BC Chen
2022-06-13  3:12       ` Rex-BC Chen
2022-06-13  3:12       ` Rex-BC Chen
2022-06-13  3:12       ` Rex-BC Chen
2022-06-13  3:12       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to " Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-30  7:55   ` CK Hu
2022-05-30  7:55     ` CK Hu
2022-05-30  7:55     ` CK Hu
2022-05-30  7:55     ` CK Hu
2022-05-30  7:55     ` CK Hu
2022-05-23 10:47 ` [PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask " Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-30  8:21   ` CK Hu
2022-05-30  8:21     ` CK Hu
2022-05-30  8:21     ` CK Hu
2022-05-30  8:21     ` CK Hu
2022-05-30  8:21     ` CK Hu
2022-05-23 10:47 ` [PATCH v10 11/21] drm/mediatek: dpi: move swap_shift " Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-30  8:38   ` CK Hu
2022-05-30  8:38     ` CK Hu
2022-05-30  8:38     ` CK Hu
2022-05-30  8:38     ` CK Hu
2022-05-30  8:38     ` CK Hu
2022-06-02 11:38     ` Rex-BC Chen
2022-06-02 11:38       ` Rex-BC Chen
2022-06-02 11:38       ` Rex-BC Chen
2022-06-02 11:38       ` Rex-BC Chen
2022-06-02 11:38       ` Rex-BC Chen
2022-06-02 12:19     ` Rex-BC Chen
2022-06-02 12:19       ` Rex-BC Chen
2022-06-02 12:19       ` Rex-BC Chen
2022-06-02 12:19       ` Rex-BC Chen
2022-06-02 12:19       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit " Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-30  8:47   ` CK Hu
2022-05-30  8:47     ` CK Hu
2022-05-30  8:47     ` CK Hu
2022-05-30  8:47     ` CK Hu
2022-05-30  8:47     ` CK Hu
2022-05-23 10:47 ` [PATCH v10 13/21] drm/mediatek: dpi: move the csc_enable bit " Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47 ` [PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-25 12:58   ` AngeloGioacchino Del Regno
2022-05-25 12:58     ` AngeloGioacchino Del Regno
2022-05-25 12:58     ` AngeloGioacchino Del Regno
2022-05-25 12:58     ` AngeloGioacchino Del Regno
2022-05-25 12:58     ` AngeloGioacchino Del Regno
2022-06-13  6:10     ` Rex-BC Chen
2022-06-13  6:10       ` Rex-BC Chen
2022-06-13  6:10       ` Rex-BC Chen
2022-06-13  6:10       ` Rex-BC Chen
2022-06-13  6:10       ` Rex-BC Chen
2022-06-02  5:48   ` Christophe JAILLET
2022-06-02  5:48     ` Christophe JAILLET
2022-06-02  5:48     ` Christophe JAILLET
2022-06-02  5:48     ` Christophe JAILLET
2022-06-02  5:48     ` Christophe JAILLET
2022-06-13  6:05     ` Rex-BC Chen
2022-06-13  6:05       ` Rex-BC Chen
2022-06-13  6:05       ` Rex-BC Chen
2022-06-13  6:05       ` Rex-BC Chen
2022-06-13  6:05       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 15/21] drm/mediatek: dpi: Only enable dpi after the bridge is enabled Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47 ` [PATCH v10 16/21] drm/meditek: dpi: Add matrix_sel helper Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47 ` [PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-06-08 16:31   ` Vinod Koul
2022-06-08 16:31     ` Vinod Koul
2022-06-08 16:31     ` Vinod Koul
2022-06-08 16:31     ` Vinod Koul
2022-06-08 16:31     ` Vinod Koul
2022-05-23 10:47 ` [PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-25  5:47   ` CK Hu
2022-05-25  5:47     ` CK Hu
2022-05-25  5:47     ` CK Hu
2022-05-25  5:47     ` CK Hu
2022-05-25  5:47     ` CK Hu
2022-05-30  9:34   ` CK Hu
2022-05-30  9:34     ` CK Hu
2022-05-30  9:34     ` CK Hu
2022-05-30  9:34     ` CK Hu
2022-05-30  9:34     ` CK Hu
2022-05-30 10:08   ` CK Hu
2022-05-30 10:08     ` CK Hu
2022-05-30 10:08     ` CK Hu
2022-05-30 10:08     ` CK Hu
2022-05-30 10:08     ` CK Hu
2022-06-07  6:21   ` CK Hu
2022-06-07  6:21     ` CK Hu
2022-06-07  6:21     ` CK Hu
2022-06-07  6:21     ` CK Hu
2022-06-07  6:21     ` CK Hu
2022-06-07 12:24     ` Rex-BC Chen
2022-06-07 12:24       ` Rex-BC Chen
2022-06-07 12:24       ` Rex-BC Chen
2022-06-07 12:24       ` Rex-BC Chen
2022-06-07 12:24       ` Rex-BC Chen
2022-06-08  2:23       ` CK Hu
2022-06-08  2:23         ` CK Hu
2022-06-08  2:23         ` CK Hu
2022-06-08  2:23         ` CK Hu
2022-06-08  2:23         ` CK Hu
2022-06-08  8:43         ` Rex-BC Chen
2022-06-08  8:43           ` Rex-BC Chen
2022-06-08  8:43           ` Rex-BC Chen
2022-06-08  8:43           ` Rex-BC Chen
2022-06-08  8:43           ` Rex-BC Chen
2022-06-08  9:15           ` CK Hu
2022-06-08  9:15             ` CK Hu
2022-06-08  9:15             ` CK Hu
2022-06-08  9:15             ` CK Hu
2022-06-08  9:15             ` CK Hu
2022-06-08 11:52             ` Rex-BC Chen
2022-06-08 11:52               ` Rex-BC Chen
2022-06-08 11:52               ` Rex-BC Chen
2022-06-08 11:52               ` Rex-BC Chen
2022-06-08 11:52               ` Rex-BC Chen
2022-06-07  6:44   ` CK Hu
2022-06-07  6:44     ` CK Hu
2022-06-07  6:44     ` CK Hu
2022-06-07  6:44     ` CK Hu
2022-06-07  6:44     ` CK Hu
2022-06-07 12:44     ` Rex-BC Chen
2022-06-07 12:44       ` Rex-BC Chen
2022-06-07 12:44       ` Rex-BC Chen
2022-06-07 12:44       ` Rex-BC Chen
2022-06-07 12:44       ` Rex-BC Chen
2022-06-08  2:44       ` CK Hu
2022-06-08  2:44         ` CK Hu
2022-06-08  2:44         ` CK Hu
2022-06-08  2:44         ` CK Hu
2022-06-08  2:44         ` CK Hu
2022-06-08 12:54         ` Rex-BC Chen
2022-06-08 12:54           ` Rex-BC Chen
2022-06-08 12:54           ` Rex-BC Chen
2022-06-08 12:54           ` Rex-BC Chen
2022-06-08 12:54           ` Rex-BC Chen
2022-06-07  7:30   ` CK Hu
2022-06-07  7:30     ` CK Hu
2022-06-07  7:30     ` CK Hu
2022-06-07  7:30     ` CK Hu
2022-06-07  7:30     ` CK Hu
2022-06-07 12:46     ` Rex-BC Chen
2022-06-07 12:46       ` Rex-BC Chen
2022-06-07 12:46       ` Rex-BC Chen
2022-06-07 12:46       ` Rex-BC Chen
2022-06-07 12:46       ` Rex-BC Chen
2022-06-07  7:47   ` CK Hu
2022-06-07  7:47     ` CK Hu
2022-06-07  7:47     ` CK Hu
2022-06-07  7:47     ` CK Hu
2022-06-07  7:47     ` CK Hu
2022-06-08 10:26     ` Rex-BC Chen
2022-06-08 10:26       ` Rex-BC Chen
2022-06-08 10:26       ` Rex-BC Chen
2022-06-08 10:26       ` Rex-BC Chen
2022-06-08 10:26       ` Rex-BC Chen
2022-06-09  2:30       ` CK Hu
2022-06-09  2:30         ` CK Hu
2022-06-09  2:30         ` CK Hu
2022-06-09  2:30         ` CK Hu
2022-06-09  2:30         ` CK Hu
2022-06-09  7:24         ` Rex-BC Chen
2022-06-09  7:24           ` Rex-BC Chen
2022-06-09  7:24           ` Rex-BC Chen
2022-06-09  7:24           ` Rex-BC Chen
2022-06-09  7:24           ` Rex-BC Chen
2022-06-07  8:01   ` CK Hu
2022-06-07  8:01     ` CK Hu
2022-06-07  8:01     ` CK Hu
2022-06-07  8:01     ` CK Hu
2022-06-07  8:01     ` CK Hu
2022-06-09  7:18     ` Rex-BC Chen
2022-06-09  7:18       ` Rex-BC Chen
2022-06-09  7:18       ` Rex-BC Chen
2022-06-09  7:18       ` Rex-BC Chen
2022-06-09  7:18       ` Rex-BC Chen
2022-06-07  8:12   ` CK Hu
2022-06-07  8:12     ` CK Hu
2022-06-07  8:12     ` CK Hu
2022-06-07  8:12     ` CK Hu
2022-06-07  8:12     ` CK Hu
2022-06-07 12:55     ` Rex-BC Chen
2022-06-07 12:55       ` Rex-BC Chen
2022-06-07 12:55       ` Rex-BC Chen
2022-06-07 12:55       ` Rex-BC Chen
2022-06-07 12:55       ` Rex-BC Chen
2022-06-07  9:04   ` CK Hu
2022-06-07  9:04     ` CK Hu
2022-06-07  9:04     ` CK Hu
2022-06-07  9:04     ` CK Hu
2022-06-07  9:04     ` CK Hu
2022-06-09  8:00     ` Rex-BC Chen
2022-06-09  8:00       ` Rex-BC Chen
2022-06-09  8:00       ` Rex-BC Chen
2022-06-09  8:00       ` Rex-BC Chen
2022-06-09  8:00       ` Rex-BC Chen
2022-06-08  8:30   ` CK Hu
2022-06-08  8:30     ` CK Hu
2022-06-08  8:30     ` CK Hu
2022-06-08  8:30     ` CK Hu
2022-06-08  8:30     ` CK Hu
2022-06-09  8:03     ` Rex-BC Chen
2022-06-09  8:03       ` Rex-BC Chen
2022-06-09  8:03       ` Rex-BC Chen
2022-06-09  8:03       ` Rex-BC Chen
2022-06-09  8:03       ` Rex-BC Chen
2022-06-08  8:45   ` CK Hu
2022-06-08  8:45     ` CK Hu
2022-06-08  8:45     ` CK Hu
2022-06-08  8:45     ` CK Hu
2022-06-08  8:45     ` CK Hu
2022-06-08  8:54     ` Rex-BC Chen
2022-06-08  8:54       ` Rex-BC Chen
2022-06-08  8:54       ` Rex-BC Chen
2022-06-08  8:54       ` Rex-BC Chen
2022-06-08  8:54       ` Rex-BC Chen
2022-06-09  9:37   ` CK Hu
2022-06-09  9:37     ` CK Hu
2022-06-09  9:37     ` CK Hu
2022-06-09  9:37     ` CK Hu
2022-06-09  9:37     ` CK Hu
2022-06-10  2:10     ` Rex-BC Chen
2022-06-10  2:10       ` Rex-BC Chen
2022-06-10  2:10       ` Rex-BC Chen
2022-06-10  2:10       ` Rex-BC Chen
2022-06-10  2:10       ` Rex-BC Chen
2022-05-23 10:47 ` [PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-25 13:04   ` AngeloGioacchino Del Regno
2022-05-25 13:04     ` AngeloGioacchino Del Regno
2022-05-25 13:04     ` AngeloGioacchino Del Regno
2022-05-25 13:04     ` AngeloGioacchino Del Regno
2022-05-25 13:04     ` AngeloGioacchino Del Regno
2022-05-23 10:47 ` [PATCH v10 20/21] drm/mediatek: add hpd debounce Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47 ` [PATCH v10 21/21] drm/mediatek: DP audio support for mt8195 Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-05-23 10:47   ` Guillaume Ranquet
2022-06-02  3:50 ` [PATCH v10 00/21] drm/mediatek: Add mt8195 DisplayPort driver Rex-BC Chen
2022-06-02  3:50   ` Rex-BC Chen
2022-06-02  3:50   ` Rex-BC Chen
2022-06-02  3:50   ` Rex-BC Chen
2022-06-02  3:50   ` Rex-BC Chen
2022-06-02  5:31   ` Rex-BC Chen
2022-06-02  5:31     ` Rex-BC Chen
2022-06-02  5:31     ` Rex-BC Chen
2022-06-02  5:31     ` Rex-BC Chen
2022-06-02  5:31     ` Rex-BC Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.