Re: [Freedreno] [PATCH 2/4] drm/msm: add hdmi cec support
Hi Arnaud, My apologies for the long delay in replying, it's been very, very busy lately. I hope I'll be able to be more responsive going forward. On 21/04/2023 18:58, Arnaud Vrac wrote: > Le ven. 21 avr. 2023 à 15:27, Hans Verkuil a écrit > : >> >> Hi Arnaud, >> >> Some review comments below... > > Hi Hans, > > For context, I first based my work on the fbdev driver from Qualcomm a > few years ago, on our own CEC framework which does not implement any > CEC protocol logic (as android does). At the time I verified that the > messages were matching the electrical and protocol spec, using manual > tests and a QD882EA analyzer. I also passed HDMI and CEC certs. > > I simply ported this work more recently to a newer kernel and the > media-cec framework, also checking the port that Qualcomm did later > on. > >> On 4/18/23 20:10, Arnaud Vrac wrote: >>> Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996 >>> and MSM8998. The hardware block can handle a single CEC logical address >>> and broadcast messages. >>> >>> Port the CEC driver from downstream msm-4.4 kernel. It has been tested >>> on MSM8998 and passes the cec-compliance tool tests. >> >> Just to verify: did you run the cec-compliance --test-adapter test? That's >> the important one to verify your own driver. > > Yes, and I also ran the cec-compliance -r 0 with a pulse8 emulating a > tv on the bus. Here's the result of cec-compliance --test-adapter: > > Find remote devices: > Polling: OK > > CEC API: > CEC_ADAP_G_CAPS: OK > Invalid ioctls: OK > CEC_DQEVENT: OK > CEC_ADAP_G/S_PHYS_ADDR: OK > CEC_ADAP_G/S_LOG_ADDRS: OK > CEC_TRANSMIT: OK > CEC_RECEIVE: OK > CEC_TRANSMIT/RECEIVE (non-blocking): OK (Presumed) > CEC_G/S_MODE: OK > warn: cec-test-adapter.cpp(1189): Too many transmits (3) > without receives > SFTs for repeating messages (>= 7): 7: 38, 8: 2 > SFTs for newly transmitted messages (>= 5): 6: 2, 7: 17 > SFTs for newly transmitted remote messages (>= 5): 6: 20 > CEC_EVENT_LOST_MSGS: OK > > Network topology: > [...] > > Total for hdmi_msm device /dev/cec0: 11, Succeeded: 11, Failed: 0, Warnings: 1 > >> >>> >>> Signed-off-by: Arnaud Vrac >>> --- >>> drivers/gpu/drm/msm/Kconfig | 8 ++ >>> drivers/gpu/drm/msm/Makefile| 1 + >>> drivers/gpu/drm/msm/hdmi/hdmi.c | 15 ++ >>> drivers/gpu/drm/msm/hdmi/hdmi.h | 18 +++ >>> drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 >>> >>> 5 files changed, 322 insertions(+) >>> >>> diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig >>> index 85f5ab1d552c4..2a02c74207935 100644 >>> --- a/drivers/gpu/drm/msm/Kconfig >>> +++ b/drivers/gpu/drm/msm/Kconfig >>> @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP >>> default y >>> help >>> Choose this option to enable HDCP state machine >>> + >>> +config DRM_MSM_HDMI_CEC >>> + bool "Enable HDMI CEC support in MSM DRM driver" >>> + depends on DRM_MSM && DRM_MSM_HDMI >>> + select CEC_CORE >>> + default y >>> + help >>> + Choose this option to enable CEC support >>> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile >>> index 7274c41228ed9..0237a2f219ac2 100644 >>> --- a/drivers/gpu/drm/msm/Makefile >>> +++ b/drivers/gpu/drm/msm/Makefile >>> @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ >>> >>> msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o >>> >>> +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o >>> msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o >>> >>> msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ >>> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c >>> b/drivers/gpu/drm/msm/hdmi/hdmi.c >>> index 3132105a2a433..1dde3890e25c0 100644 >>> --- a/drivers/gpu/drm/msm/hdmi/hdmi.c >>> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c >>> @@ -11,6 +11,8 @@ >>> #include >>> #include >>> >>> +#include >>> + >>> #include >>> #include "hdmi.h" >>> >>> @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id) >>> if (hdmi->hdcp_ctrl) >>> msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl); >>> >>> + /* Process CEC: */ >>> + msm_hdmi_cec_irq(hdmi); >>> + >>> /* TODO audio.. */ >>> >>> return IRQ_HANDLED; >>> @@ -66,6 +71,8 @@ static void msm_hdmi_destroy(struct hdmi *hdmi) >>>*/ >>> if (hdmi->workq) >>> destroy_workqueue(hdmi->workq); >>> + >>> + msm_hdmi_cec_exit(hdmi); >>> msm_hdmi_hdcp_destroy(hdmi); >>> >>> if (hdmi->i2c) >>> @@ -139,6 +146,8 @@ static int msm_hdmi_init(struct hdmi *hdmi) >>> hdmi->hdcp_ctrl = NULL; >>> } >>> >>> + msm_hdmi_cec_init(hdmi); >>> + >>> return 0; >>> >>> fail: >>> @@ -198,6 +207,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, >>> >>> drm_connector_attach_encoder(hdmi->connector, hdmi->encoder); >>> >>> +
Re: [Freedreno] [PATCH 2/4] drm/msm: add hdmi cec support
Le ven. 21 avr. 2023 à 15:27, Hans Verkuil a écrit : > > Hi Arnaud, > > Some review comments below... Hi Hans, For context, I first based my work on the fbdev driver from Qualcomm a few years ago, on our own CEC framework which does not implement any CEC protocol logic (as android does). At the time I verified that the messages were matching the electrical and protocol spec, using manual tests and a QD882EA analyzer. I also passed HDMI and CEC certs. I simply ported this work more recently to a newer kernel and the media-cec framework, also checking the port that Qualcomm did later on. > On 4/18/23 20:10, Arnaud Vrac wrote: > > Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996 > > and MSM8998. The hardware block can handle a single CEC logical address > > and broadcast messages. > > > > Port the CEC driver from downstream msm-4.4 kernel. It has been tested > > on MSM8998 and passes the cec-compliance tool tests. > > Just to verify: did you run the cec-compliance --test-adapter test? That's > the important one to verify your own driver. Yes, and I also ran the cec-compliance -r 0 with a pulse8 emulating a tv on the bus. Here's the result of cec-compliance --test-adapter: Find remote devices: Polling: OK CEC API: CEC_ADAP_G_CAPS: OK Invalid ioctls: OK CEC_DQEVENT: OK CEC_ADAP_G/S_PHYS_ADDR: OK CEC_ADAP_G/S_LOG_ADDRS: OK CEC_TRANSMIT: OK CEC_RECEIVE: OK CEC_TRANSMIT/RECEIVE (non-blocking): OK (Presumed) CEC_G/S_MODE: OK warn: cec-test-adapter.cpp(1189): Too many transmits (3) without receives SFTs for repeating messages (>= 7): 7: 38, 8: 2 SFTs for newly transmitted messages (>= 5): 6: 2, 7: 17 SFTs for newly transmitted remote messages (>= 5): 6: 20 CEC_EVENT_LOST_MSGS: OK Network topology: [...] Total for hdmi_msm device /dev/cec0: 11, Succeeded: 11, Failed: 0, Warnings: 1 > > > > > Signed-off-by: Arnaud Vrac > > --- > > drivers/gpu/drm/msm/Kconfig | 8 ++ > > drivers/gpu/drm/msm/Makefile| 1 + > > drivers/gpu/drm/msm/hdmi/hdmi.c | 15 ++ > > drivers/gpu/drm/msm/hdmi/hdmi.h | 18 +++ > > drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 > > > > 5 files changed, 322 insertions(+) > > > > diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig > > index 85f5ab1d552c4..2a02c74207935 100644 > > --- a/drivers/gpu/drm/msm/Kconfig > > +++ b/drivers/gpu/drm/msm/Kconfig > > @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP > > default y > > help > > Choose this option to enable HDCP state machine > > + > > +config DRM_MSM_HDMI_CEC > > + bool "Enable HDMI CEC support in MSM DRM driver" > > + depends on DRM_MSM && DRM_MSM_HDMI > > + select CEC_CORE > > + default y > > + help > > + Choose this option to enable CEC support > > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > > index 7274c41228ed9..0237a2f219ac2 100644 > > --- a/drivers/gpu/drm/msm/Makefile > > +++ b/drivers/gpu/drm/msm/Makefile > > @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ > > > > msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o > > > > +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o > > msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o > > > > msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ > > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c > > b/drivers/gpu/drm/msm/hdmi/hdmi.c > > index 3132105a2a433..1dde3890e25c0 100644 > > --- a/drivers/gpu/drm/msm/hdmi/hdmi.c > > +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c > > @@ -11,6 +11,8 @@ > > #include > > #include > > > > +#include > > + > > #include > > #include "hdmi.h" > > > > @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id) > > if (hdmi->hdcp_ctrl) > > msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl); > > > > + /* Process CEC: */ > > + msm_hdmi_cec_irq(hdmi); > > + > > /* TODO audio.. */ > > > > return IRQ_HANDLED; > > @@ -66,6 +71,8 @@ static void msm_hdmi_destroy(struct hdmi *hdmi) > >*/ > > if (hdmi->workq) > > destroy_workqueue(hdmi->workq); > > + > > + msm_hdmi_cec_exit(hdmi); > > msm_hdmi_hdcp_destroy(hdmi); > > > > if (hdmi->i2c) > > @@ -139,6 +146,8 @@ static int msm_hdmi_init(struct hdmi *hdmi) > > hdmi->hdcp_ctrl = NULL; > > } > > > > + msm_hdmi_cec_init(hdmi); > > + > > return 0; > > > > fail: > > @@ -198,6 +207,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, > > > > drm_connector_attach_encoder(hdmi->connector, hdmi->encoder); > > > > + if (hdmi->cec_adap) { > > + struct cec_connector_info conn_info; > > + cec_fill_conn_info_from_drm(_info, hdmi->connector); > > + cec_s_conn_info(hdmi->cec_adap, _info); > > + } > > + > > ret = devm_request_irq(dev->dev, hdmi->irq, > >
Re: [Freedreno] [PATCH 2/4] drm/msm: add hdmi cec support
Hi Arnaud, Some review comments below... On 4/18/23 20:10, Arnaud Vrac wrote: > Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996 > and MSM8998. The hardware block can handle a single CEC logical address > and broadcast messages. > > Port the CEC driver from downstream msm-4.4 kernel. It has been tested > on MSM8998 and passes the cec-compliance tool tests. Just to verify: did you run the cec-compliance --test-adapter test? That's the important one to verify your own driver. > > Signed-off-by: Arnaud Vrac > --- > drivers/gpu/drm/msm/Kconfig | 8 ++ > drivers/gpu/drm/msm/Makefile| 1 + > drivers/gpu/drm/msm/hdmi/hdmi.c | 15 ++ > drivers/gpu/drm/msm/hdmi/hdmi.h | 18 +++ > drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 > > 5 files changed, 322 insertions(+) > > diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig > index 85f5ab1d552c4..2a02c74207935 100644 > --- a/drivers/gpu/drm/msm/Kconfig > +++ b/drivers/gpu/drm/msm/Kconfig > @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP > default y > help > Choose this option to enable HDCP state machine > + > +config DRM_MSM_HDMI_CEC > + bool "Enable HDMI CEC support in MSM DRM driver" > + depends on DRM_MSM && DRM_MSM_HDMI > + select CEC_CORE > + default y > + help > + Choose this option to enable CEC support > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > index 7274c41228ed9..0237a2f219ac2 100644 > --- a/drivers/gpu/drm/msm/Makefile > +++ b/drivers/gpu/drm/msm/Makefile > @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ > > msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o > > +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o > msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o > > msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c > index 3132105a2a433..1dde3890e25c0 100644 > --- a/drivers/gpu/drm/msm/hdmi/hdmi.c > +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c > @@ -11,6 +11,8 @@ > #include > #include > > +#include > + > #include > #include "hdmi.h" > > @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id) > if (hdmi->hdcp_ctrl) > msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl); > > + /* Process CEC: */ > + msm_hdmi_cec_irq(hdmi); > + > /* TODO audio.. */ > > return IRQ_HANDLED; > @@ -66,6 +71,8 @@ static void msm_hdmi_destroy(struct hdmi *hdmi) >*/ > if (hdmi->workq) > destroy_workqueue(hdmi->workq); > + > + msm_hdmi_cec_exit(hdmi); > msm_hdmi_hdcp_destroy(hdmi); > > if (hdmi->i2c) > @@ -139,6 +146,8 @@ static int msm_hdmi_init(struct hdmi *hdmi) > hdmi->hdcp_ctrl = NULL; > } > > + msm_hdmi_cec_init(hdmi); > + > return 0; > > fail: > @@ -198,6 +207,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, > > drm_connector_attach_encoder(hdmi->connector, hdmi->encoder); > > + if (hdmi->cec_adap) { > + struct cec_connector_info conn_info; > + cec_fill_conn_info_from_drm(_info, hdmi->connector); > + cec_s_conn_info(hdmi->cec_adap, _info); > + } > + > ret = devm_request_irq(dev->dev, hdmi->irq, > msm_hdmi_irq, IRQF_TRIGGER_HIGH, > "hdmi_isr", hdmi); > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h > index e8dbee50637fa..c639bd87f4b8f 100644 > --- a/drivers/gpu/drm/msm/hdmi/hdmi.h > +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h > @@ -29,6 +29,7 @@ struct hdmi_audio { > }; > > struct hdmi_hdcp_ctrl; > +struct cec_adapter; > > struct hdmi { > struct drm_device *dev; > @@ -73,6 +74,7 @@ struct hdmi { > struct workqueue_struct *workq; > > struct hdmi_hdcp_ctrl *hdcp_ctrl; > + struct cec_adapter *cec_adap; > > /* > * spinlock to protect registers shared by different execution > @@ -261,4 +263,20 @@ static inline void msm_hdmi_hdcp_off(struct > hdmi_hdcp_ctrl *hdcp_ctrl) {} > static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} > #endif > > +/* > + * cec > + */ > +#ifdef CONFIG_DRM_MSM_HDMI_CEC > +int msm_hdmi_cec_init(struct hdmi *hdmi); > +void msm_hdmi_cec_exit(struct hdmi *hdmi); > +void msm_hdmi_cec_irq(struct hdmi *hdmi); > +#else > +static inline int msm_hdmi_cec_init(struct hdmi *hdmi) > +{ > + return -ENXIO; > +} > +static inline void msm_hdmi_cec_exit(struct hdmi *hdmi) {} > +static inline void msm_hdmi_cec_irq(struct hdmi *hdmi) {} > +#endif > + > #endif /* __HDMI_CONNECTOR_H__ */ > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_cec.c > b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c > new file mode 100644 > index 0..51326e493e5da > --- /dev/null > +++ b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c > @@ -0,0 +1,280 @@ > +#include > +#include > + > +#include "hdmi.h" > +
Re: [Freedreno] [PATCH 2/4] drm/msm: add hdmi cec support
On Thu, 20 Apr 2023 at 10:24, Arnaud Vrac wrote: > > Le jeu. 20 avr. 2023 à 02:20, Dmitry Baryshkov > a écrit : > > > > On 18/04/2023 21:10, Arnaud Vrac wrote: > > > Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996 > > > and MSM8998. The hardware block can handle a single CEC logical address > > > and broadcast messages. > > > > > > Port the CEC driver from downstream msm-4.4 kernel. It has been tested > > > on MSM8998 and passes the cec-compliance tool tests. > > > > > > Signed-off-by: Arnaud Vrac > > > --- > > > drivers/gpu/drm/msm/Kconfig | 8 ++ > > > drivers/gpu/drm/msm/Makefile| 1 + > > > drivers/gpu/drm/msm/hdmi/hdmi.c | 15 ++ > > > drivers/gpu/drm/msm/hdmi/hdmi.h | 18 +++ > > > drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 > > > > > > 5 files changed, 322 insertions(+) > > > > > > diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig > > > index 85f5ab1d552c4..2a02c74207935 100644 > > > --- a/drivers/gpu/drm/msm/Kconfig > > > +++ b/drivers/gpu/drm/msm/Kconfig > > > @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP > > > default y > > > help > > > Choose this option to enable HDCP state machine > > > + > > > +config DRM_MSM_HDMI_CEC > > > + bool "Enable HDMI CEC support in MSM DRM driver" > > > + depends on DRM_MSM && DRM_MSM_HDMI > > > + select CEC_CORE > > > + default y > > > + help > > > + Choose this option to enable CEC support > > > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > > > index 7274c41228ed9..0237a2f219ac2 100644 > > > --- a/drivers/gpu/drm/msm/Makefile > > > +++ b/drivers/gpu/drm/msm/Makefile > > > @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ > > > > > > msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o > > > > > > +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o > > > msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o > > > > > > msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ > > > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c > > > b/drivers/gpu/drm/msm/hdmi/hdmi.c > > > index 3132105a2a433..1dde3890e25c0 100644 > > > --- a/drivers/gpu/drm/msm/hdmi/hdmi.c > > > +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c > > > @@ -11,6 +11,8 @@ > > > #include > > > #include > > > > > > +#include > > > + > > > #include > > > #include "hdmi.h" > > > > > > @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id) > > > if (hdmi->hdcp_ctrl) > > > msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl); > > > > > > + /* Process CEC: */ > > > + msm_hdmi_cec_irq(hdmi); > > > + > > > /* TODO audio.. */ > > > > > > return IRQ_HANDLED; > > > @@ -66,6 +71,8 @@ static void msm_hdmi_destroy(struct hdmi *hdmi) > > >*/ > > > if (hdmi->workq) > > > destroy_workqueue(hdmi->workq); > > > + > > > + msm_hdmi_cec_exit(hdmi); > > > msm_hdmi_hdcp_destroy(hdmi); > > > > > > if (hdmi->i2c) > > > @@ -139,6 +146,8 @@ static int msm_hdmi_init(struct hdmi *hdmi) > > > hdmi->hdcp_ctrl = NULL; > > > } > > > > > > + msm_hdmi_cec_init(hdmi); > > > + > > > return 0; > > > > > > fail: > > > @@ -198,6 +207,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, > > > > > > drm_connector_attach_encoder(hdmi->connector, hdmi->encoder); > > > > > > + if (hdmi->cec_adap) { > > > + struct cec_connector_info conn_info; > > > + cec_fill_conn_info_from_drm(_info, hdmi->connector); > > > + cec_s_conn_info(hdmi->cec_adap, _info); > > > + } > > > + > > > ret = devm_request_irq(dev->dev, hdmi->irq, > > > msm_hdmi_irq, IRQF_TRIGGER_HIGH, > > > "hdmi_isr", hdmi); > > > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h > > > b/drivers/gpu/drm/msm/hdmi/hdmi.h > > > index e8dbee50637fa..c639bd87f4b8f 100644 > > > --- a/drivers/gpu/drm/msm/hdmi/hdmi.h > > > +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h > > > @@ -29,6 +29,7 @@ struct hdmi_audio { > > > }; > > > > > > struct hdmi_hdcp_ctrl; > > > +struct cec_adapter; > > > > > > struct hdmi { > > > struct drm_device *dev; > > > @@ -73,6 +74,7 @@ struct hdmi { > > > struct workqueue_struct *workq; > > > > > > struct hdmi_hdcp_ctrl *hdcp_ctrl; > > > + struct cec_adapter *cec_adap; > > > > > > /* > > > * spinlock to protect registers shared by different execution > > > @@ -261,4 +263,20 @@ static inline void msm_hdmi_hdcp_off(struct > > > hdmi_hdcp_ctrl *hdcp_ctrl) {} > > > static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) > > > {} > > > #endif > > > > > > +/* > > > + * cec > > > + */ > > > +#ifdef CONFIG_DRM_MSM_HDMI_CEC > > > +int msm_hdmi_cec_init(struct hdmi *hdmi); > > > +void msm_hdmi_cec_exit(struct hdmi *hdmi); > > > +void msm_hdmi_cec_irq(struct hdmi *hdmi); > > > +#else > > > +static inline int msm_hdmi_cec_init(struct hdmi
Re: [Freedreno] [PATCH 2/4] drm/msm: add hdmi cec support
Le jeu. 20 avr. 2023 à 02:20, Dmitry Baryshkov a écrit : > > On 18/04/2023 21:10, Arnaud Vrac wrote: > > Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996 > > and MSM8998. The hardware block can handle a single CEC logical address > > and broadcast messages. > > > > Port the CEC driver from downstream msm-4.4 kernel. It has been tested > > on MSM8998 and passes the cec-compliance tool tests. > > > > Signed-off-by: Arnaud Vrac > > --- > > drivers/gpu/drm/msm/Kconfig | 8 ++ > > drivers/gpu/drm/msm/Makefile| 1 + > > drivers/gpu/drm/msm/hdmi/hdmi.c | 15 ++ > > drivers/gpu/drm/msm/hdmi/hdmi.h | 18 +++ > > drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 > > > > 5 files changed, 322 insertions(+) > > > > diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig > > index 85f5ab1d552c4..2a02c74207935 100644 > > --- a/drivers/gpu/drm/msm/Kconfig > > +++ b/drivers/gpu/drm/msm/Kconfig > > @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP > > default y > > help > > Choose this option to enable HDCP state machine > > + > > +config DRM_MSM_HDMI_CEC > > + bool "Enable HDMI CEC support in MSM DRM driver" > > + depends on DRM_MSM && DRM_MSM_HDMI > > + select CEC_CORE > > + default y > > + help > > + Choose this option to enable CEC support > > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > > index 7274c41228ed9..0237a2f219ac2 100644 > > --- a/drivers/gpu/drm/msm/Makefile > > +++ b/drivers/gpu/drm/msm/Makefile > > @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ > > > > msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o > > > > +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o > > msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o > > > > msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ > > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c > > b/drivers/gpu/drm/msm/hdmi/hdmi.c > > index 3132105a2a433..1dde3890e25c0 100644 > > --- a/drivers/gpu/drm/msm/hdmi/hdmi.c > > +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c > > @@ -11,6 +11,8 @@ > > #include > > #include > > > > +#include > > + > > #include > > #include "hdmi.h" > > > > @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id) > > if (hdmi->hdcp_ctrl) > > msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl); > > > > + /* Process CEC: */ > > + msm_hdmi_cec_irq(hdmi); > > + > > /* TODO audio.. */ > > > > return IRQ_HANDLED; > > @@ -66,6 +71,8 @@ static void msm_hdmi_destroy(struct hdmi *hdmi) > >*/ > > if (hdmi->workq) > > destroy_workqueue(hdmi->workq); > > + > > + msm_hdmi_cec_exit(hdmi); > > msm_hdmi_hdcp_destroy(hdmi); > > > > if (hdmi->i2c) > > @@ -139,6 +146,8 @@ static int msm_hdmi_init(struct hdmi *hdmi) > > hdmi->hdcp_ctrl = NULL; > > } > > > > + msm_hdmi_cec_init(hdmi); > > + > > return 0; > > > > fail: > > @@ -198,6 +207,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, > > > > drm_connector_attach_encoder(hdmi->connector, hdmi->encoder); > > > > + if (hdmi->cec_adap) { > > + struct cec_connector_info conn_info; > > + cec_fill_conn_info_from_drm(_info, hdmi->connector); > > + cec_s_conn_info(hdmi->cec_adap, _info); > > + } > > + > > ret = devm_request_irq(dev->dev, hdmi->irq, > > msm_hdmi_irq, IRQF_TRIGGER_HIGH, > > "hdmi_isr", hdmi); > > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h > > b/drivers/gpu/drm/msm/hdmi/hdmi.h > > index e8dbee50637fa..c639bd87f4b8f 100644 > > --- a/drivers/gpu/drm/msm/hdmi/hdmi.h > > +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h > > @@ -29,6 +29,7 @@ struct hdmi_audio { > > }; > > > > struct hdmi_hdcp_ctrl; > > +struct cec_adapter; > > > > struct hdmi { > > struct drm_device *dev; > > @@ -73,6 +74,7 @@ struct hdmi { > > struct workqueue_struct *workq; > > > > struct hdmi_hdcp_ctrl *hdcp_ctrl; > > + struct cec_adapter *cec_adap; > > > > /* > > * spinlock to protect registers shared by different execution > > @@ -261,4 +263,20 @@ static inline void msm_hdmi_hdcp_off(struct > > hdmi_hdcp_ctrl *hdcp_ctrl) {} > > static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} > > #endif > > > > +/* > > + * cec > > + */ > > +#ifdef CONFIG_DRM_MSM_HDMI_CEC > > +int msm_hdmi_cec_init(struct hdmi *hdmi); > > +void msm_hdmi_cec_exit(struct hdmi *hdmi); > > +void msm_hdmi_cec_irq(struct hdmi *hdmi); > > +#else > > +static inline int msm_hdmi_cec_init(struct hdmi *hdmi) > > +{ > > + return -ENXIO; > > +} > > +static inline void msm_hdmi_cec_exit(struct hdmi *hdmi) {} > > +static inline void msm_hdmi_cec_irq(struct hdmi *hdmi) {} > > +#endif > > + > > #endif /* __HDMI_CONNECTOR_H__ */ > > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_cec.c > > b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c > > new file
Re: [Freedreno] [PATCH 2/4] drm/msm: add hdmi cec support
On 18/04/2023 21:10, Arnaud Vrac wrote: Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996 and MSM8998. The hardware block can handle a single CEC logical address and broadcast messages. Port the CEC driver from downstream msm-4.4 kernel. It has been tested on MSM8998 and passes the cec-compliance tool tests. Signed-off-by: Arnaud Vrac --- drivers/gpu/drm/msm/Kconfig | 8 ++ drivers/gpu/drm/msm/Makefile| 1 + drivers/gpu/drm/msm/hdmi/hdmi.c | 15 ++ drivers/gpu/drm/msm/hdmi/hdmi.h | 18 +++ drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 5 files changed, 322 insertions(+) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 85f5ab1d552c4..2a02c74207935 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP default y help Choose this option to enable HDCP state machine + +config DRM_MSM_HDMI_CEC + bool "Enable HDMI CEC support in MSM DRM driver" + depends on DRM_MSM && DRM_MSM_HDMI + select CEC_CORE + default y + help + Choose this option to enable CEC support diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7274c41228ed9..0237a2f219ac2 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 3132105a2a433..1dde3890e25c0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -11,6 +11,8 @@ #include #include +#include + #include #include "hdmi.h" @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id) if (hdmi->hdcp_ctrl) msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl); + /* Process CEC: */ + msm_hdmi_cec_irq(hdmi); + /* TODO audio.. */ return IRQ_HANDLED; @@ -66,6 +71,8 @@ static void msm_hdmi_destroy(struct hdmi *hdmi) */ if (hdmi->workq) destroy_workqueue(hdmi->workq); + + msm_hdmi_cec_exit(hdmi); msm_hdmi_hdcp_destroy(hdmi); if (hdmi->i2c) @@ -139,6 +146,8 @@ static int msm_hdmi_init(struct hdmi *hdmi) hdmi->hdcp_ctrl = NULL; } + msm_hdmi_cec_init(hdmi); + return 0; fail: @@ -198,6 +207,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, drm_connector_attach_encoder(hdmi->connector, hdmi->encoder); + if (hdmi->cec_adap) { + struct cec_connector_info conn_info; + cec_fill_conn_info_from_drm(_info, hdmi->connector); + cec_s_conn_info(hdmi->cec_adap, _info); + } + ret = devm_request_irq(dev->dev, hdmi->irq, msm_hdmi_irq, IRQF_TRIGGER_HIGH, "hdmi_isr", hdmi); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index e8dbee50637fa..c639bd87f4b8f 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -29,6 +29,7 @@ struct hdmi_audio { }; struct hdmi_hdcp_ctrl; +struct cec_adapter; struct hdmi { struct drm_device *dev; @@ -73,6 +74,7 @@ struct hdmi { struct workqueue_struct *workq; struct hdmi_hdcp_ctrl *hdcp_ctrl; + struct cec_adapter *cec_adap; /* * spinlock to protect registers shared by different execution @@ -261,4 +263,20 @@ static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} #endif +/* + * cec + */ +#ifdef CONFIG_DRM_MSM_HDMI_CEC +int msm_hdmi_cec_init(struct hdmi *hdmi); +void msm_hdmi_cec_exit(struct hdmi *hdmi); +void msm_hdmi_cec_irq(struct hdmi *hdmi); +#else +static inline int msm_hdmi_cec_init(struct hdmi *hdmi) +{ + return -ENXIO; +} +static inline void msm_hdmi_cec_exit(struct hdmi *hdmi) {} +static inline void msm_hdmi_cec_irq(struct hdmi *hdmi) {} +#endif + #endif /* __HDMI_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_cec.c b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c new file mode 100644 index 0..51326e493e5da --- /dev/null +++ b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c @@ -0,0 +1,280 @@ +#include +#include + +#include "hdmi.h" + +#define HDMI_CEC_INT_MASK ( \ + HDMI_CEC_INT_TX_DONE_MASK | \ + HDMI_CEC_INT_TX_ERROR_MASK | \ + HDMI_CEC_INT_RX_DONE_MASK) + +struct hdmi_cec_ctrl { + struct hdmi *hdmi; + struct work_struct work; + spinlock_t lock; + u32 irq_status; + u32 tx_status; + u32 tx_retransmits; +}; + +static int
[Freedreno] [PATCH 2/4] drm/msm: add hdmi cec support
Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996 and MSM8998. The hardware block can handle a single CEC logical address and broadcast messages. Port the CEC driver from downstream msm-4.4 kernel. It has been tested on MSM8998 and passes the cec-compliance tool tests. Signed-off-by: Arnaud Vrac --- drivers/gpu/drm/msm/Kconfig | 8 ++ drivers/gpu/drm/msm/Makefile| 1 + drivers/gpu/drm/msm/hdmi/hdmi.c | 15 ++ drivers/gpu/drm/msm/hdmi/hdmi.h | 18 +++ drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 5 files changed, 322 insertions(+) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 85f5ab1d552c4..2a02c74207935 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP default y help Choose this option to enable HDCP state machine + +config DRM_MSM_HDMI_CEC + bool "Enable HDMI CEC support in MSM DRM driver" + depends on DRM_MSM && DRM_MSM_HDMI + select CEC_CORE + default y + help + Choose this option to enable CEC support diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7274c41228ed9..0237a2f219ac2 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 3132105a2a433..1dde3890e25c0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -11,6 +11,8 @@ #include #include +#include + #include #include "hdmi.h" @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id) if (hdmi->hdcp_ctrl) msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl); + /* Process CEC: */ + msm_hdmi_cec_irq(hdmi); + /* TODO audio.. */ return IRQ_HANDLED; @@ -66,6 +71,8 @@ static void msm_hdmi_destroy(struct hdmi *hdmi) */ if (hdmi->workq) destroy_workqueue(hdmi->workq); + + msm_hdmi_cec_exit(hdmi); msm_hdmi_hdcp_destroy(hdmi); if (hdmi->i2c) @@ -139,6 +146,8 @@ static int msm_hdmi_init(struct hdmi *hdmi) hdmi->hdcp_ctrl = NULL; } + msm_hdmi_cec_init(hdmi); + return 0; fail: @@ -198,6 +207,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, drm_connector_attach_encoder(hdmi->connector, hdmi->encoder); + if (hdmi->cec_adap) { + struct cec_connector_info conn_info; + cec_fill_conn_info_from_drm(_info, hdmi->connector); + cec_s_conn_info(hdmi->cec_adap, _info); + } + ret = devm_request_irq(dev->dev, hdmi->irq, msm_hdmi_irq, IRQF_TRIGGER_HIGH, "hdmi_isr", hdmi); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index e8dbee50637fa..c639bd87f4b8f 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -29,6 +29,7 @@ struct hdmi_audio { }; struct hdmi_hdcp_ctrl; +struct cec_adapter; struct hdmi { struct drm_device *dev; @@ -73,6 +74,7 @@ struct hdmi { struct workqueue_struct *workq; struct hdmi_hdcp_ctrl *hdcp_ctrl; + struct cec_adapter *cec_adap; /* * spinlock to protect registers shared by different execution @@ -261,4 +263,20 @@ static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} #endif +/* + * cec + */ +#ifdef CONFIG_DRM_MSM_HDMI_CEC +int msm_hdmi_cec_init(struct hdmi *hdmi); +void msm_hdmi_cec_exit(struct hdmi *hdmi); +void msm_hdmi_cec_irq(struct hdmi *hdmi); +#else +static inline int msm_hdmi_cec_init(struct hdmi *hdmi) +{ + return -ENXIO; +} +static inline void msm_hdmi_cec_exit(struct hdmi *hdmi) {} +static inline void msm_hdmi_cec_irq(struct hdmi *hdmi) {} +#endif + #endif /* __HDMI_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_cec.c b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c new file mode 100644 index 0..51326e493e5da --- /dev/null +++ b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c @@ -0,0 +1,280 @@ +#include +#include + +#include "hdmi.h" + +#define HDMI_CEC_INT_MASK ( \ + HDMI_CEC_INT_TX_DONE_MASK | \ + HDMI_CEC_INT_TX_ERROR_MASK | \ + HDMI_CEC_INT_RX_DONE_MASK) + +struct hdmi_cec_ctrl { + struct hdmi *hdmi; + struct work_struct work; + spinlock_t lock; + u32 irq_status; + u32 tx_status; + u32 tx_retransmits; +}; + +static int msm_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) +{ +