Re: Call for an EDID parsing library
Hi Pekka, On 07/04/2021 10:44, Pekka Paalanen wrote: > Hi all, > > with display servers proliferating thanks to Wayland, and the Linux > kernel exposing only a very limited set of information based on EDID > (rightfully so!), the need to interpret EDID blobs is spreading even > more. I would like to start the discussion about starting a project to > develop a shared library for parsing EDID blobs. This is not the first > time either, other people have suggested it years and years ago already, > but apparently it didn't quite materialise as far as I know. > > Right now, it seems that more or less every display server and other > KMS application is hand-rolling its own EDID parsing code, even for the > most trivial information (monitor make, model, and serial number). With > HDR and color management support coming to Wayland, the need to parse > more things out of EDID will only increase. These things are not > exposed by the kernel, and most of these things have no use for the > kernel either. > > My personal motivation for this is that I don't want to be developing > or reviewing yet another partial EDID parser implementation in Weston. > > I recall ponderings about sharing the same EDID parsing code between > the kernel and userspace, but I got the feeling that it would be a > hindrance in process more than a benefit from sharing code. It would > need to live in the kernel tree, to be managed with the kernel > development process, use the kernel "standard libraries", and adhere to > kernel programming style - all which are good and fine, but maybe also > more restricting than useful in this case. Therefore I would suggest a > userspace-only library. > > Everyone hand-rolling their own parsing code has the obvious > disadvantages. In the opposite, I would expect a new shared EDID > parsing library and project to: > - be hosted under gitlab.freedesktop.org > - be MIT licensed > - offer at least a C ABI > - employ mandatory Gitlab CI to ensure with sample EDID blobs that it > cannot regress > > Prior art can be found in various places. I believe Xorg xserver has > its battle-tested EDID parsing code. Ajax once played with the idea in > https://cgit.freedesktop.org/~ajax/libminitru/ . Then we have > https://git.linuxtv.org/edid-decode.git too which has code and test > data but not a C ABI (right?). Correct, I moved it to C++. It was never designed to be a library, it was primarily meant to turn an EDID into a human readable format. And these days it is also a very powerful tool to verify EDIDs. It is the most complete EDID parser I know based on the various standards. > It does not necessarily need to be a new project. Would edid-decode > project be open to adding a C library ABI? I would be open to that. The best way would be to create a C library that turns the EDID blocks into C structures, while edid-decode itself remains C++ and uses the C library to do the parsing. While edid-decode supports a large range of Extension Blocks, a C library could probably limit itself to the base block, CTA-861 blocks and DisplayID blocks. > > edid-decode is already MIT licensed and seems to have a lot of code, > too, but that's all I know for now. It is as far as I know the most complete parser. > > Would there be anyone interested to take lead or work on a project like > this? I can assist/advice and do code reviews, but I don't have the time myself to do the actual work. > > Personally I don't think I'd be working on it, but I would be really > happy to use it in Weston. > > Should it be a new project, or grow inside edid-decode or something > else? I think it would make sense if it is grown as a library used by edid-decode. The edid-decode utility is under active maintenance and follows the latest EDID standards, so that will probably help the quality of the library. My main requirement would be that the edid-decode functionality is not affected, especially the conformity checks are still performed. And that support for new/updated EDID standards can easily be implemented, but that's exactly what you would want in an edid library. > > I believe MIT license is important to have wide adoption of it. C ABI > similarly. Also that it would be a "small" library without heavy > dependencies. It shouldn't need any dependencies. edid-decode doesn't need any either except for -lm, which is probably not needed for the library part. > What do you think? Could anyone spare their time for this? Didn't you just volunteer? :-) :-) Regards, Hans > > Who would be interested in using it if this library appeared? > > > Thanks, > pq > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Call for an EDID parsing library
On 07/04/2021 12:31, Jani Nikula wrote: > On Wed, 07 Apr 2021, Hans Verkuil wrote: >> It is the most complete EDID parser I know based on the various standards. > > Does it support pure DisplayID in addition to DisplayID blocks embedded > to EDID extension blocks? I think we'll be needing that sometime in the > near future. (We don't yet support that in the kernel either.) It doesn't, but that shouldn't be too hard to implement. Do you have examples of that? If I had some, then I could implement support for it in edid-decode. Regards, Hans ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 0/2] drm/bridge: dw-hdmi: disable loading of DW-HDMI CEC sub-driver
On 16/04/2021 13:38, Neil Armstrong wrote: > On 16/04/2021 11:58, Laurent Pinchart wrote: >> Hi Neil, >> >> On Fri, Apr 16, 2021 at 11:27:35AM +0200, Neil Armstrong wrote: >>> This adds DW-HDMI driver a glue option to disable loading of the CEC >>> sub-driver. >>> >>> On some SoCs, the CEC functionality is enabled in the IP config bits, but >>> the >>> CEC bus is non-functional like on Amlogic SoCs, where the CEC config bit is >>> set >>> but the DW-HDMI CEC signal is not connected to a physical pin, leading to >>> some >>> confusion when the DW-HDMI CEC controller can't communicate on the bus. >> >> If we can't trust the CEC config bit, would it be better to not use it >> at all, and instead let each platform glue logic tell whether to enable >> CEC or not ? > > Actually, the CEC config bit is right, the HW exists and should be > functional, but > this bit doesn't tell if the CEC signal is connected to something. > > This lies in the IP integration, like other bits under the > "amlogic,meson-*-dw-hdmi" > umbrella. > > The first attempt was by Hans using DT, but adding a property in DT for a > vendor > specific compatible doesn't make sense. Another idea would be to describe the > CEC signal endpoint like we do for video signal, but I think this is out of > scope and > this solution is much simpler and straightforward, and it's more an exception > than > a general use case to solve. While a DT property might not make sense in this particular case, I still believe that it is a perfectly valid approach in general: whether or not the CEC pin is connected is at the hardware level decision, it is not something that software can detect. If the designer of the board didn't connect it, then the only place you can define that is in the device tree. Anyway, for meson I am fine with this solution. At least it prevents creating a non-functioning cec device. So for this series: Acked-by: Hans Verkuil Regards, Hans > > Neil > >> >>> Jernej Skrabec (1): >>> drm/bridge/synopsys: dw-hdmi: Add an option to suppress loading CEC >>> driver >>> >>> Neil Armstrong (1): >>> drm/meson: dw-hdmi: disable DW-HDMI CEC sub-driver >>> >>> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +- >>> drivers/gpu/drm/meson/meson_dw_hdmi.c | 1 + >>> include/drm/bridge/dw_hdmi.h | 2 ++ >>> 3 files changed, 4 insertions(+), 1 deletion(-) >>> >> > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCHv2 1/6] drm: drm_bridge: add connector_attach/detach bridge ops
On 16/04/2021 09:46, Tomi Valkeinen wrote: > Hi Hans, > > On 02/03/2021 18:23, Hans Verkuil wrote: >> Add bridge connector_attach/detach ops. These ops are called when a >> bridge is attached or detached to a drm_connector. These ops can be >> used to register and unregister an HDMI CEC adapter for a bridge that >> supports CEC. >> >> Signed-off-by: Hans Verkuil >> --- >> drivers/gpu/drm/drm_bridge_connector.c | 9 + >> include/drm/drm_bridge.h | 27 ++ >> 2 files changed, 36 insertions(+) >> >> diff --git a/drivers/gpu/drm/drm_bridge_connector.c >> b/drivers/gpu/drm/drm_bridge_connector.c >> index 791379816837..07db71d4f5b3 100644 >> --- a/drivers/gpu/drm/drm_bridge_connector.c >> +++ b/drivers/gpu/drm/drm_bridge_connector.c >> @@ -203,6 +203,11 @@ static void drm_bridge_connector_destroy(struct >> drm_connector *connector) >> { >> struct drm_bridge_connector *bridge_connector = >> to_drm_bridge_connector(connector); >> +struct drm_bridge *bridge; >> + >> +drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) >> +if (bridge->funcs->connector_detach) >> +bridge->funcs->connector_detach(bridge, connector); >> >> if (bridge_connector->bridge_hpd) { >> struct drm_bridge *hpd = bridge_connector->bridge_hpd; >> @@ -375,6 +380,10 @@ struct drm_connector *drm_bridge_connector_init(struct >> drm_device *drm, >> connector->polled = DRM_CONNECTOR_POLL_CONNECT >>| DRM_CONNECTOR_POLL_DISCONNECT; >> >> +drm_for_each_bridge_in_chain(encoder, bridge) >> +if (bridge->funcs->connector_attach) >> +bridge->funcs->connector_attach(bridge, connector); >> + >> return connector; >> } >> EXPORT_SYMBOL_GPL(drm_bridge_connector_init); >> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h >> index 2195daa289d2..3320a6ebd253 100644 >> --- a/include/drm/drm_bridge.h >> +++ b/include/drm/drm_bridge.h >> @@ -629,6 +629,33 @@ struct drm_bridge_funcs { >> * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops. >> */ >> void (*hpd_disable)(struct drm_bridge *bridge); >> + >> +/** >> + * @connector_attach: >> + * >> + * This callback is invoked whenever our bridge is being attached to a >> + * &drm_connector. This is where an HDMI CEC adapter can be registered. >> + * Note that this callback expects that this op always succeeds. Since >> + * HDMI CEC support is an optional feature, any failure to register a >> + * CEC adapter must be ignored since video output will still work >> + * without CEC. >> + * > > Even if CEC support is optional, the callback itself is generic. > Wouldn't it be better to make this function return an error, and for > CEC, just return 0 if CEC won't get registered correctly? I'll do that. > > Also, I personally like things to fail if something doesn't go right, > instead of continuing, if that thing is never supposed to happen in > normal situations. E.g. if CEC registration fails because we're out of > memory, I think the op should fail too. If that happens you have no video output. And that's a lot more important than CEC! As you suggested, I'll have the cec connector_attach just return 0. Regards, Hans > > Tomi > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv3 1/6] drm: drm_bridge: add connector_attach/detach bridge ops
Add bridge connector_attach/detach ops. These ops are called when a bridge is attached or detached to a drm_connector. These ops can be used to register and unregister an HDMI CEC adapter for a bridge that supports CEC. Signed-off-by: Hans Verkuil --- drivers/gpu/drm/drm_bridge_connector.c | 25 +++- include/drm/drm_bridge.h | 27 ++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index 791379816837..0676677badfe 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -203,6 +203,11 @@ static void drm_bridge_connector_destroy(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) + if (bridge->funcs->connector_detach) + bridge->funcs->connector_detach(bridge, connector); if (bridge_connector->bridge_hpd) { struct drm_bridge *hpd = bridge_connector->bridge_hpd; @@ -318,6 +323,7 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, struct i2c_adapter *ddc = NULL; struct drm_bridge *bridge; int connector_type; + int ret; bridge_connector = kzalloc(sizeof(*bridge_connector), GFP_KERNEL); if (!bridge_connector) @@ -375,6 +381,23 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - return connector; + ret = 0; + /* call connector_attach for all bridges */ + drm_for_each_bridge_in_chain(encoder, bridge) { + if (!bridge->funcs->connector_attach) + continue; + ret = bridge->funcs->connector_attach(bridge, connector); + if (ret) + break; + } + if (!ret) + return connector; + + /* on error, detach any previously successfully attached connectors */ + list_for_each_entry_continue_reverse(bridge, &(encoder)->bridge_chain, +chain_node) + if (bridge->funcs->connector_detach) + bridge->funcs->connector_detach(bridge, connector); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(drm_bridge_connector_init); diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 2195daa289d2..333fbc3a03e9 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -629,6 +629,33 @@ struct drm_bridge_funcs { * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops. */ void (*hpd_disable)(struct drm_bridge *bridge); + + /** +* @connector_attach: +* +* This callback is invoked whenever our bridge is being attached to a +* &drm_connector. This is where an HDMI CEC adapter can be registered. +* +* The @connector_attach callback is optional. +* +* RETURNS: +* +* Zero on success, error code on failure. +*/ + int (*connector_attach)(struct drm_bridge *bridge, + struct drm_connector *conn); + + /** +* @connector_detach: +* +* This callback is invoked whenever our bridge is being detached from a +* &drm_connector. This is where an HDMI CEC adapter can be +* unregistered. +* +* The @connector_detach callback is optional. +*/ + void (*connector_detach)(struct drm_bridge *bridge, +struct drm_connector *conn); }; /** -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv3 2/6] drm/omapdrm/dss/hdmi4: switch to the connector bridge ops
Implement the new connector_attach/detach bridge ops. This makes it possible to associate a CEC adapter with a drm connector, which helps userspace determine which cec device node belongs to which drm connector. Signed-off-by: Hans Verkuil Reviewed-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 28 ++--- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 9 +--- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 7 --- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 35b750cebaeb..e29d4d186265 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -482,6 +482,23 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, return edid; } +static int hdmi4_bridge_connector_attach(struct drm_bridge *bridge, +struct drm_connector *conn) +{ + struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); + + hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp, conn); + return 0; +} + +static void hdmi4_bridge_connector_detach(struct drm_bridge *bridge, + struct drm_connector *conn) +{ + struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); + + hdmi4_cec_uninit(&hdmi->core); +} + static const struct drm_bridge_funcs hdmi4_bridge_funcs = { .attach = hdmi4_bridge_attach, .mode_set = hdmi4_bridge_mode_set, @@ -492,6 +509,8 @@ static const struct drm_bridge_funcs hdmi4_bridge_funcs = { .atomic_disable = hdmi4_bridge_disable, .hpd_notify = hdmi4_bridge_hpd_notify, .get_edid = hdmi4_bridge_get_edid, + .connector_attach = hdmi4_bridge_connector_attach, + .connector_detach = hdmi4_bridge_connector_detach, }; static void hdmi4_bridge_init(struct omap_hdmi *hdmi) @@ -647,14 +666,10 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data) if (r) goto err_runtime_put; - r = hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp); - if (r) - goto err_pll_uninit; - r = hdmi_audio_register(hdmi); if (r) { DSSERR("Registering HDMI audio failed\n"); - goto err_cec_uninit; + goto err_pll_uninit; } hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs, @@ -664,8 +679,6 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data) return 0; -err_cec_uninit: - hdmi4_cec_uninit(&hdmi->core); err_pll_uninit: hdmi_pll_uninit(&hdmi->pll); err_runtime_put: @@ -682,7 +695,6 @@ static void hdmi4_unbind(struct device *dev, struct device *master, void *data) if (hdmi->audio_pdev) platform_device_unregister(hdmi->audio_pdev); - hdmi4_cec_uninit(&hdmi->core); hdmi_pll_uninit(&hdmi->pll); } diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 43592c1cf081..80ec52c9c846 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -335,10 +335,10 @@ void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) } int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, - struct hdmi_wp_data *wp) + struct hdmi_wp_data *wp, struct drm_connector *conn) { - const u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | -CEC_CAP_PASSTHROUGH | CEC_CAP_RC; + const u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO; + struct cec_connector_info conn_info; int ret; core->adap = cec_allocate_adapter(&hdmi_cec_adap_ops, core, @@ -346,6 +346,8 @@ int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, ret = PTR_ERR_OR_ZERO(core->adap); if (ret < 0) return ret; + cec_fill_conn_info_from_drm(&conn_info, conn); + cec_s_conn_info(core->adap, &conn_info); core->wp = wp; /* Disable clock initially, hdmi_cec_adap_enable() manages it */ @@ -354,6 +356,7 @@ int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, ret = cec_register_adapter(core->adap, &pdev->dev); if (ret < 0) { cec_delete_adapter(core->adap); + core->adap = NULL; return ret; } return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h index 0292337c97cc..b59a54c3040e 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h @@ -29,7 +29,7 @@ struct platform_device; void hdmi4_cec_set_phys_addr(
[PATCHv3 6/6] drm/omapdrm/dss/hdmi5: add CEC support
Add HDMI CEC support for OMAP5. Signed-off-by: Hans Verkuil Reviewed-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/Kconfig | 8 + drivers/gpu/drm/omapdrm/Makefile | 1 + drivers/gpu/drm/omapdrm/dss/hdmi.h | 1 + drivers/gpu/drm/omapdrm/dss/hdmi5.c | 64 +-- drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c | 209 +++ drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h | 42 + drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 35 +++- drivers/gpu/drm/omapdrm/dss/hdmi5_core.h | 33 +++- 8 files changed, 374 insertions(+), 19 deletions(-) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig index e7281da5bc6a..08866ac7d869 100644 --- a/drivers/gpu/drm/omapdrm/Kconfig +++ b/drivers/gpu/drm/omapdrm/Kconfig @@ -80,6 +80,14 @@ config OMAP5_DSS_HDMI Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI specification. +config OMAP5_DSS_HDMI_CEC + bool "Enable HDMI CEC support for OMAP5" + depends on OMAP5_DSS_HDMI + select CEC_CORE + default y + help + When selected the HDMI transmitter will support the CEC feature. + config OMAP2_DSS_SDI bool "SDI support" default n diff --git a/drivers/gpu/drm/omapdrm/Makefile b/drivers/gpu/drm/omapdrm/Makefile index 21e8277ff88f..0732bd2dae1e 100644 --- a/drivers/gpu/drm/omapdrm/Makefile +++ b/drivers/gpu/drm/omapdrm/Makefile @@ -29,6 +29,7 @@ omapdrm-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += dss/hdmi_common.o dss/hdmi_wp.o \ omapdrm-$(CONFIG_OMAP4_DSS_HDMI) += dss/hdmi4.o dss/hdmi4_core.o omapdrm-$(CONFIG_OMAP4_DSS_HDMI_CEC) += dss/hdmi4_cec.o omapdrm-$(CONFIG_OMAP5_DSS_HDMI) += dss/hdmi5.o dss/hdmi5_core.o +omapdrm-$(CONFIG_OMAP5_DSS_HDMI_CEC) += dss/hdmi5_cec.o ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG obj-$(CONFIG_DRM_OMAP) += omapdrm.o diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h index c4a4e07f0b99..72d8ae441da6 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h @@ -261,6 +261,7 @@ struct hdmi_core_data { struct hdmi_wp_data *wp; unsigned int core_pwr_cnt; struct cec_adapter *adap; + struct clk *cec_clk; }; static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 65085d886da5..11941d7b1d81 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -29,12 +29,14 @@ #include #include #include +#include #include #include #include "omapdss.h" #include "hdmi5_core.h" +#include "hdmi5_cec.h" #include "dss.h" static int hdmi_runtime_get(struct omap_hdmi *hdmi) @@ -105,6 +107,9 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); } + if (irqstatus & HDMI_IRQ_CORE) + hdmi5_core_handle_irqs(&hdmi->core); + return IRQ_HANDLED; } @@ -112,9 +117,12 @@ static int hdmi_power_on_core(struct omap_hdmi *hdmi) { int r; + if (hdmi->core.core_pwr_cnt++) + return 0; + r = regulator_enable(hdmi->vdda_reg); if (r) - return r; + goto err_reg_enable; r = hdmi_runtime_get(hdmi); if (r) @@ -129,12 +137,17 @@ static int hdmi_power_on_core(struct omap_hdmi *hdmi) err_runtime_get: regulator_disable(hdmi->vdda_reg); +err_reg_enable: + hdmi->core.core_pwr_cnt--; return r; } static void hdmi_power_off_core(struct omap_hdmi *hdmi) { + if (--hdmi->core.core_pwr_cnt) + return; + hdmi->core_enabled = false; hdmi_runtime_put(hdmi); @@ -168,9 +181,9 @@ static int hdmi_power_on_full(struct omap_hdmi *hdmi) pc, &hdmi_cinfo); /* disable and clear irqs */ - hdmi_wp_clear_irqenable(&hdmi->wp, 0x); + hdmi_wp_clear_irqenable(&hdmi->wp, ~HDMI_IRQ_CORE); hdmi_wp_set_irqstatus(&hdmi->wp, - hdmi_wp_get_irqstatus(&hdmi->wp)); + hdmi_wp_get_irqstatus(&hdmi->wp) & ~HDMI_IRQ_CORE); r = dss_pll_enable(&hdmi->pll.pll); if (r) { @@ -225,7 +238,7 @@ static int hdmi_power_on_full(struct omap_hdmi *hdmi) static void hdmi_power_off_full(struct omap_hdmi *hdmi) { - hdmi_wp_clear_irqenable(&hdmi->wp, 0x); + hdmi_wp_clear_irqenable(&hdmi->wp, ~HDMI_IRQ_CORE); hdmi_wp_video_stop(&hdmi->wp); @@ -273,11 +286,11 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd) REG_FLD_MOD(hd->wp.base, HDMI_
[PATCHv3 4/6] dt-bindings: display: ti: ti, omap5-dss.txt: add cec clock
The cec clock is required as well in order to support HDMI CEC, document this. Signed-off-by: Hans Verkuil Reviewed-by: Tomi Valkeinen Acked-by: Rob Herring --- Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt b/Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt index 20861218649f..c321c67472f0 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt +++ b/Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt @@ -89,8 +89,8 @@ Required properties: - interrupts: the HDMI interrupt line - ti,hwmods: "dss_hdmi" - vdda-supply: vdda power supply -- clocks: handles to fclk and pll clock -- clock-names: "fck", "sys_clk" +- clocks: handles to fclk, pll and cec clock +- clock-names: "fck", "sys_clk", "cec" Optional nodes: - Video port for HDMI output -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv3 3/6] drm/omapdrm/dss/hdmi4: simplify CEC Phys Addr handling
Switch to using cec_s_phys_addr_from_edid() instead of a two-step process of calling cec_get_edid_phys_addr() followed by cec_s_phys_addr(). Signed-off-by: Hans Verkuil Reviewed-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 13 ++--- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 4 ++-- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 5 +++-- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index e29d4d186265..40f791c668f4 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -432,7 +432,7 @@ static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge, struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); if (status == connector_status_disconnected) - hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID); + hdmi4_cec_set_phys_addr(&hdmi->core, NULL); } static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, @@ -440,7 +440,6 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, { struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); struct edid *edid = NULL; - unsigned int cec_addr; bool need_enable; int r; @@ -466,15 +465,7 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, hdmi_runtime_put(hdmi); mutex_unlock(&hdmi->lock); - if (edid && edid->extensions) { - unsigned int len = (edid->extensions + 1) * EDID_LENGTH; - - cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL); - } else { - cec_addr = CEC_PHYS_ADDR_INVALID; - } - - hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr); + hdmi4_cec_set_phys_addr(&hdmi->core, edid); if (need_enable) hdmi4_core_disable(&hdmi->core); diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 80ec52c9c846..cf406d86c845 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -329,9 +329,9 @@ static const struct cec_adap_ops hdmi_cec_adap_ops = { .adap_transmit = hdmi_cec_adap_transmit, }; -void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) +void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, struct edid *edid) { - cec_s_phys_addr(core->adap, pa, false); + cec_s_phys_addr_from_edid(core->adap, edid); } int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h index b59a54c3040e..16bf259643b7 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h @@ -26,13 +26,14 @@ struct platform_device; /* HDMI CEC funcs */ #ifdef CONFIG_OMAP4_DSS_HDMI_CEC -void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa); +void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, struct edid *edid); void hdmi4_cec_irq(struct hdmi_core_data *core); int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, struct hdmi_wp_data *wp, struct drm_connector *conn); void hdmi4_cec_uninit(struct hdmi_core_data *core); #else -static inline void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) +static inline void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, + struct edid *edid) { } -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv3 5/6] dra7.dtsi/omap5.dtsi: add cec clock
Add cec clock to the dra7 and omap5 device trees. Signed-off-by: Hans Verkuil Acked-by: Tony Lindgren Reviewed-by: Tomi Valkeinen --- arch/arm/boot/dts/dra7.dtsi | 5 +++-- arch/arm/boot/dts/omap5.dtsi | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index ce1194744f84..efe579ddb324 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -879,8 +879,9 @@ hdmi: encoder@0 { interrupts = ; status = "disabled"; clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>, -<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; +<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>, +<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "sys_clk", "cec"; dmas = <&sdma_xbar 76>; dma-names = "audio_tx"; }; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index e025b7c9a357..6726e1f1b07c 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -586,8 +586,9 @@ hdmi: encoder@0 { interrupts = ; status = "disabled"; clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 9>, -<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; +<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>, +<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "sys_clk", "cec"; dmas = <&sdma 76>; dma-names = "audio_tx"; }; -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv3 0/6] drm/omap: hdmi: improve hdmi4 CEC, add CEC for hdmi5
This series improves the drm_bridge support for CEC by introducing two new bridge ops in the first patch, and using those in the second patch. This makes it possible to call cec_s_conn_info() and set CEC_CAP_CONNECTOR_INFO for the CEC adapter, so userspace can associate the CEC adapter with the corresponding DRM connector. The third patch simplifies CEC physical address handling by using the cec_s_phys_addr_from_edid helper function that didn't exist when this code was originally written. The fourth patch adds the cec clock to ti,omap5-dss.txt. The fifth patch the missing cec clock to the dra7 and omap5 device tree, and the last patch adds CEC support to the OMAP5 driver. Tested with a Pandaboard and a Beagle X15 board. Regards, Hans Changes since v2: - connector_attach can now return an error. If an error is returned then connector_detach is called in reverse order to clean up any previous connector_attach calls. - connector_attach in hdmi4 and hdmi5 now return 0. Changes since v1: - as per suggestion from Laurent, changed cec_init/exit to connector_attach/_detach which are just called for all bridges. The DRM_BRIDGE_OP_CEC was dropped. - added patch to add the cec clock to ti,omap5-dss.txt - swapped the order of the last two patches - incorporated Tomi's suggestions for the hdmi5 CEC support. Hans Verkuil (6): drm: drm_bridge: add connector_attach/detach bridge ops drm/omapdrm/dss/hdmi4: switch to the connector bridge ops drm/omapdrm/dss/hdmi4: simplify CEC Phys Addr handling dt-bindings: display: ti: ti,omap5-dss.txt: add cec clock dra7.dtsi/omap5.dtsi: add cec clock drm/omapdrm/dss/hdmi5: add CEC support .../bindings/display/ti/ti,omap5-dss.txt | 4 +- arch/arm/boot/dts/dra7.dtsi | 5 +- arch/arm/boot/dts/omap5.dtsi | 5 +- drivers/gpu/drm/drm_bridge_connector.c| 25 ++- drivers/gpu/drm/omapdrm/Kconfig | 8 + drivers/gpu/drm/omapdrm/Makefile | 1 + drivers/gpu/drm/omapdrm/dss/hdmi.h| 1 + drivers/gpu/drm/omapdrm/dss/hdmi4.c | 41 ++-- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 13 +- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 12 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 64 +- drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c | 209 ++ drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h | 42 drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 35 ++- drivers/gpu/drm/omapdrm/dss/hdmi5_core.h | 33 ++- include/drm/drm_bridge.h | 27 +++ 16 files changed, 470 insertions(+), 55 deletions(-) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/bridge: adv7511: fix support for large EDIDs
While testing support for large (> 256 bytes) EDIDs on the Renesas Koelsch board I noticed that the adv7511 bridge driver only read the first two blocks. The media V4L2 version for the adv7511 (drivers/media/i2c/adv7511-v4l2.c) handled this correctly. Besides a simple bug when setting the segment register (it was set to the block number instead of block / 2), the logic of the code was also weird. In particular reading the DDC_STATUS is odd: this is unrelated to EDID reading. The reworked code just waits for any EDID segment reads to finish (this does nothing if the a segment is already read), checks if the desired segment matches the read segment, and if not, then it requests the new segment and waits again for the EDID segment to be read. Finally it checks if the currently buffered EDID segment contains the desired EDID block, and if not it will update the EDID buffer from the adv7511. Tested with my Koelsch board and with EDIDs of 1, 2, 3 and 4 blocks. Signed-off-by: Hans Verkuil --- Testing on the Renesas board also requires these two adv7604 patches if you want to test with an HDMI cable between the HDMI input and output: https://patchwork.linuxtv.org/project/linux-media/patch/00882808-472a-d429-c565-a701da579...@xs4all.nl/ https://patchwork.linuxtv.org/project/linux-media/patch/c7093e76-ffb4-b19c-f576-b264f935a...@xs4all.nl/ --- diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 76555ae64e9c..9e8db1c60167 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -328,6 +328,7 @@ static void adv7511_set_link_config(struct adv7511 *adv7511, static void __adv7511_power_on(struct adv7511 *adv7511) { adv7511->current_edid_segment = -1; + adv7511->edid_read = false; regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, ADV7511_POWER_POWER_DOWN, 0); @@ -529,29 +530,35 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block, struct adv7511 *adv7511 = data; struct i2c_msg xfer[2]; uint8_t offset; + unsigned int cur_segment; unsigned int i; int ret; if (len > 128) return -EINVAL; - if (adv7511->current_edid_segment != block / 2) { - unsigned int status; + /* wait for any EDID segment reads to finish */ + adv7511_wait_for_edid(adv7511, 200); - ret = regmap_read(adv7511->regmap, ADV7511_REG_DDC_STATUS, - &status); + ret = regmap_read(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, &cur_segment); + if (ret < 0) + return ret; + + /* +* If the current read segment does not match what we need, then +* write the new segment and wait for it to be read. +*/ + if (cur_segment != block / 2) { + adv7511->edid_read = false; + cur_segment = block / 2; + regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, +cur_segment); + ret = adv7511_wait_for_edid(adv7511, 200); if (ret < 0) return ret; + } - if (status != 2) { - adv7511->edid_read = false; - regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, -block); - ret = adv7511_wait_for_edid(adv7511, 200); - if (ret < 0) - return ret; - } - + if (adv7511->current_edid_segment != cur_segment) { /* Break this apart, hopefully more I2C controllers will * support 64 byte transfers than 256 byte transfers */ @@ -579,7 +586,7 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block, offset += 64; } - adv7511->current_edid_segment = block / 2; + adv7511->current_edid_segment = cur_segment; } if (block % 2 == 0) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: adv7511: fix support for large EDIDs
Hi Laurent, Thank you for the review. On 26/03/2021 02:00, Laurent Pinchart wrote: > Hi Hans, > > Thank you for the patch. > > On Wed, Mar 24, 2021 at 09:53:32AM +0100, Hans Verkuil wrote: >> While testing support for large (> 256 bytes) EDIDs on the Renesas >> Koelsch board I noticed that the adv7511 bridge driver only read the >> first two blocks. >> >> The media V4L2 version for the adv7511 (drivers/media/i2c/adv7511-v4l2.c) >> handled this correctly. >> >> Besides a simple bug when setting the segment register (it was set to the >> block number instead of block / 2), the logic of the code was also weird. >> In particular reading the DDC_STATUS is odd: this is unrelated to EDID >> reading. > > Bits 3:0 of DDC_STATUS report the DDC controller state, which can be > used to wait until the DDC controller is idle (it reports, among other > possible states, if an EDID read is in progress). Other options are > possible of course, including waiting for ADV7511_INT0_EDID_READY as > done in adv7511_wait_for_edid(), but I wonder if the !irq case in > adv7511_wait_for_edid() wouldn't be better of busy-looping on the DDC > status instead of running the interrupt handler manually. That's > unrelated to this patch though. > >> The reworked code just waits for any EDID segment reads to finish (this >> does nothing if the a segment is already read), checks if the desired >> segment matches the read segment, and if not, then it requests the new >> segment and waits again for the EDID segment to be read. >> >> Finally it checks if the currently buffered EDID segment contains the >> desired EDID block, and if not it will update the EDID buffer from >> the adv7511. >> >> Tested with my Koelsch board and with EDIDs of 1, 2, 3 and 4 blocks. >> >> Signed-off-by: Hans Verkuil >> --- >> Testing on the Renesas board also requires these two adv7604 patches >> if you want to test with an HDMI cable between the HDMI input and output: >> >> https://patchwork.linuxtv.org/project/linux-media/patch/00882808-472a-d429-c565-a701da579...@xs4all.nl/ >> https://patchwork.linuxtv.org/project/linux-media/patch/c7093e76-ffb4-b19c-f576-b264f935a...@xs4all.nl/ >> --- >> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c >> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c >> index 76555ae64e9c..9e8db1c60167 100644 >> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c >> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c >> @@ -328,6 +328,7 @@ static void adv7511_set_link_config(struct adv7511 >> *adv7511, >> static void __adv7511_power_on(struct adv7511 *adv7511) >> { >> adv7511->current_edid_segment = -1; >> +adv7511->edid_read = false; >> >> regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, >> ADV7511_POWER_POWER_DOWN, 0); >> @@ -529,29 +530,35 @@ static int adv7511_get_edid_block(void *data, u8 *buf, >> unsigned int block, >> struct adv7511 *adv7511 = data; >> struct i2c_msg xfer[2]; >> uint8_t offset; >> +unsigned int cur_segment; >> unsigned int i; >> int ret; >> >> if (len > 128) >> return -EINVAL; >> >> -if (adv7511->current_edid_segment != block / 2) { >> -unsigned int status; >> +/* wait for any EDID segment reads to finish */ >> +adv7511_wait_for_edid(adv7511, 200); > > Why do we need to wait for the EDID read to complete here ? Does the > ADV7511 initiate an EDID read by itself that we need to wait for it to > complete ? Yes. When powered on it will automatically start to read the first segment. > >> >> -ret = regmap_read(adv7511->regmap, ADV7511_REG_DDC_STATUS, >> - &status); >> +ret = regmap_read(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, >> &cur_segment); >> +if (ret < 0) >> +return ret; > > Do we need to read this from the device, can't we instead use > current_edid_segment ? We can, provided we take into account that after poweron current_edid_segment is -1, and in that case we must not set ADV7511_REG_EDID_SEGMENT again. I'll make that change. > >> + >> +/* >> + * If the current read segment does not match what we need, then >> + * write the new segment and wait for it to be read. >> + */ >> +if (cur_segment != block / 2) { >> +adv7511->edid_read = false; >> +cur_segment = block / 2; >> +regmap_w
Re: [PATCH] drm/bridge: adv7511: fix support for large EDIDs
On 26/03/2021 02:00, Laurent Pinchart wrote: > Hi Hans, > > Thank you for the patch. > > On Wed, Mar 24, 2021 at 09:53:32AM +0100, Hans Verkuil wrote: >> While testing support for large (> 256 bytes) EDIDs on the Renesas >> Koelsch board I noticed that the adv7511 bridge driver only read the >> first two blocks. >> >> The media V4L2 version for the adv7511 (drivers/media/i2c/adv7511-v4l2.c) >> handled this correctly. >> >> Besides a simple bug when setting the segment register (it was set to the >> block number instead of block / 2), the logic of the code was also weird. >> In particular reading the DDC_STATUS is odd: this is unrelated to EDID >> reading. > > Bits 3:0 of DDC_STATUS report the DDC controller state, which can be > used to wait until the DDC controller is idle (it reports, among other > possible states, if an EDID read is in progress). Other options are > possible of course, including waiting for ADV7511_INT0_EDID_READY as > done in adv7511_wait_for_edid(), but I wonder if the !irq case in > adv7511_wait_for_edid() wouldn't be better of busy-looping on the DDC > status instead of running the interrupt handler manually. That's > unrelated to this patch though. The DDC status tests for other things as well, including HDCP. I think it is pure luck that this code even worked: if (adv7511->current_edid_segment != block / 2) { unsigned int status; ret = regmap_read(adv7511->regmap, ADV7511_REG_DDC_STATUS, &status); if (ret < 0) return ret; if (status != 2) { adv7511->edid_read = false; regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, block); ret = adv7511_wait_for_edid(adv7511, 200); if (ret < 0) return ret; } What happens on power on is that the adv7511 starts reading the EDID. So the DDC_STATUS is 1 (Reading EDID). This code is called, it falls in the status != 2 block, it writes the EDID_SEGMENT with 0 (it already is 0 after a power on), then waits for the EDID read to finish. The only reason this works is that this code is called fast enough after the device is powered on that it is still reading the EDID. It fails if you want to read the next segment, since in that case the status is 2 (IDLE) and it will never write the new segment to the EDID_SEGMENT register. And besides, status wasn't ANDed with 0xf either, and HDCP might also be ongoing (should that be enabled in the future). Regards, Hans ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv2] drm/bridge: adv7511: fix support for large EDIDs
While testing support for large (> 256 bytes) EDIDs on the Renesas Koelsch board I noticed that the adv7511 bridge driver only read the first two blocks. The media V4L2 version for the adv7511 (drivers/media/i2c/adv7511-v4l2.c) handled this correctly. Besides a simple bug when setting the segment register (it was set to the block number instead of block / 2), the logic of the code was also weird. In particular reading the DDC_STATUS is odd: this is unrelated to EDID reading. The reworked code just waits for any EDID segment reads to finish (this does nothing if the a segment is already read), checks if the desired segment matches the read segment, and if not, then it requests the new segment and waits again for the EDID segment to be read. Finally it checks if the currently buffered EDID segment contains the desired EDID block, and if not it will update the EDID buffer from the adv7511. Tested with my Koelsch board and with EDIDs of 1, 2, 3 and 4 blocks. Signed-off-by: Hans Verkuil Tested-by: Niklas Söderlund --- Changes since v2: make current_edid_segment an int (it's set to -1 after all) and use that instead of reading ADV7511_REG_EDID_SEGMENT. Also sprinkle a few comments in the code. --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 2 +- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 40 +--- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index a9bb734366ae..3dd29c578fc9 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -342,7 +342,7 @@ struct adv7511 { unsigned int f_audio; unsigned int audio_source; - unsigned int current_edid_segment; + int current_edid_segment; uint8_t edid_buf[256]; bool edid_read; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 76555ae64e9c..43fefdd8d92b 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -327,7 +327,12 @@ static void adv7511_set_link_config(struct adv7511 *adv7511, static void __adv7511_power_on(struct adv7511 *adv7511) { + /* +* The adv7511 will start reading the first EDID segment as +* soon as it is powered on. +*/ adv7511->current_edid_segment = -1; + adv7511->edid_read = false; regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, ADV7511_POWER_POWER_DOWN, 0); @@ -526,6 +531,7 @@ static int adv7511_wait_for_edid(struct adv7511 *adv7511, int timeout) static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len) { + unsigned int need_segment = block / 2; struct adv7511 *adv7511 = data; struct i2c_msg xfer[2]; uint8_t offset; @@ -535,23 +541,29 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block, if (len > 128) return -EINVAL; - if (adv7511->current_edid_segment != block / 2) { - unsigned int status; + /* wait for any ongoing EDID segment reads to finish */ + adv7511_wait_for_edid(adv7511, 200); - ret = regmap_read(adv7511->regmap, ADV7511_REG_DDC_STATUS, - &status); + /* +* If the current read segment does not match what we need, then +* write the new segment and wait for it to be read. +* +* Note that after power on the adv7511 starts reading segment 0 +* of the EDID automatically. So if current_edid_segment < 0, then +* we do not need to write the EDID_SEGMENT register again, since +* it is already reading segment 0. +*/ + if (adv7511->current_edid_segment >= 0 && + adv7511->current_edid_segment != need_segment) { + adv7511->edid_read = false; + regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, +need_segment); + ret = adv7511_wait_for_edid(adv7511, 200); if (ret < 0) return ret; + } - if (status != 2) { - adv7511->edid_read = false; - regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, -block); - ret = adv7511_wait_for_edid(adv7511, 200); - if (ret < 0) - return ret; - } - + if (adv7511->current_edid_segment != need_segment) { /* Break this apart, hopefully more I2C controllers will * support 64 byte transfers than 256 byte transfers */ @@ -579,7 +591,7 @@ static int adv7511_get_edid_block(v
Re: [PATCH v2 00/15] drm/vc4: hdmi: Add CEC support for the BCM2711
On 12/01/2021 16:24, Hans Verkuil wrote: > Hi Maxime, > > On 11/01/2021 15:22, Maxime Ripard wrote: >> Hi, >> >> Here's a series introducing the CEC support for the BCM2711 found on the >> RaspberryPi4. >> >> The BCM2711 HDMI controller uses a similar layout for the CEC registers, the >> main difference being that the interrupt handling part is now shared between >> both HDMI controllers. >> >> This series is mainly about fixing a couple of bugs, reworking the driver to >> support having two different interrupts, one for each direction, provided by >> an >> external irqchip, and enables the irqchip driver for the controller we have. >> >> This has been tested on an RPi3 and RPi4, but requires the latest firmware. >> It's is based on the 10 and 12 bpc series. > > Thank you for this series, I plan to test this later this week. Testing is delayed: my microHDMI to HDMI adapter has problems with the CEC pin (possibly not connected at all). I've ordered adapter cables (hopefully of better quality), but those haven't arrived yet. I expect them later this week. Regards, Hans > > Regards, > > Hans > >> >> Here is the cec-compliance output: >> >> pi@raspberrypi:~$ cec-ctl --tuner -p 1.0.0.0 >> The CEC adapter doesn't allow setting the physical address manually, ignore >> this option. >> >> Driver Info: >> Driver Name: vc4_hdmi >> Adapter Name : vc4 >> Capabilities : 0x010e >> Logical Addresses >> Transmit >> Passthrough >> Driver version : 5.10.0 >> Available Logical Addresses: 1 >> Physical Address : 1.0.0.0 >> Logical Address Mask : 0x0008 >> CEC Version: 2.0 >> Vendor ID : 0x000c03 (HDMI) >> OSD Name : Tuner >> Logical Addresses : 1 (Allow RC Passthrough) >> >>Logical Address : 3 (Tuner 1) >> Primary Device Type: Tuner >> Logical Address Type : Tuner >> All Device Types : Tuner >> RC TV Profile : None >> Device Features: >> None >> >> pi@raspberrypi:~$ cec-compliance >> cec-compliance SHA : not available >> Driver Info: >> Driver Name: vc4_hdmi >> Adapter Name : vc4 >> Capabilities : 0x010e >> Logical Addresses >> Transmit >> Passthrough >> Driver version : 5.10.0 >> Available Logical Addresses: 1 >> Physical Address : 1.0.0.0 >> Logical Address Mask : 0x0008 >> CEC Version: 2.0 >> Vendor ID : 0x000c03 (HDMI) >> OSD Name : Tuner >> Logical Addresses : 1 (Allow RC Passthrough) >> >>Logical Address : 3 (Tuner 1) >> Primary Device Type: Tuner >> Logical Address Type : Tuner >> All Device Types : Tuner >> RC TV Profile : None >> Device Features: >> None >> >> Compliance test for device /dev/cec0: >> >> The test results mean the following: >> OK Supported correctly by the device. >> OK (Not Supported) Not supported and not mandatory for the device. >> OK (Presumed) Presumably supported. Manually check to confirm. >> OK (Unexpected) Supported correctly but is not expected to be >> supported for this device. >> OK (Refused)Supported by the device, but was refused. >> FAILFailed and was expected to be supported by this >> device. >> >> Find remote devices: >> Polling: OK >> >> Network topology: >> System Information for device 0 (TV) from device 3 (Tuner 1): >> CEC Version: 2.0 >> Physical Address : 0.0.0.0 >> Primary Device Type: TV >> Vendor ID : 0x000c03 >> OSD Name : 'TV ' >> Power Status : Tx, OK, Rx, OK, Feature Abort >> >> Total: 1, Succeeded: 1, Failed: 0, Warnings: 0 >> >> pi@
Re: [PATCH v7 14/17] media/videobuf1|2: Mark follow_pfn usage as unsafe
On 27/11/2020 17:41, Daniel Vetter wrote: > The media model assumes that buffers are all preallocated, so that > when a media pipeline is running we never miss a deadline because the > buffers aren't allocated or available. > > This means we cannot fix the v4l follow_pfn usage through > mmu_notifier, without breaking how this all works. The only real fix > is to deprecate userptr support for VM_IO | VM_PFNMAP mappings and > tell everyone to cut over to dma-buf memory sharing for zerocopy. > > userptr for normal memory will keep working as-is, this only affects > the zerocopy userptr usage enabled in 50ac952d2263 ("[media] > videobuf2-dma-sg: Support io userptr operations on io memory"). > > Acked-by: Tomasz Figa Acked-by: Hans Verkuil Regards, Hans > Signed-off-by: Daniel Vetter > Cc: Jason Gunthorpe > Cc: Kees Cook > Cc: Dan Williams > Cc: Andrew Morton > Cc: John Hubbard > Cc: Jérôme Glisse > Cc: Jan Kara > Cc: Dan Williams > Cc: linux...@kvack.org > Cc: linux-arm-ker...@lists.infradead.org > Cc: linux-samsung-...@vger.kernel.org > Cc: linux-me...@vger.kernel.org > Cc: Pawel Osciak > Cc: Marek Szyprowski > Cc: Kyungmin Park > Cc: Tomasz Figa > Cc: Laurent Dufour > Cc: Vlastimil Babka > Cc: Daniel Jordan > Cc: Michel Lespinasse > Signed-off-by: Daniel Vetter > -- > v3: > - Reference the commit that enabled the zerocopy userptr use case to > make it abundandtly clear that this patch only affects that, and not > normal memory userptr. The old commit message already explained that > normal memory userptr is unaffected, but I guess that was not clear > enough. > --- > drivers/media/common/videobuf2/frame_vector.c | 2 +- > drivers/media/v4l2-core/videobuf-dma-contig.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/common/videobuf2/frame_vector.c > b/drivers/media/common/videobuf2/frame_vector.c > index a0e65481a201..1a82ec13ea00 100644 > --- a/drivers/media/common/videobuf2/frame_vector.c > +++ b/drivers/media/common/videobuf2/frame_vector.c > @@ -70,7 +70,7 @@ int get_vaddr_frames(unsigned long start, unsigned int > nr_frames, > break; > > while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) { > - err = follow_pfn(vma, start, &nums[ret]); > + err = unsafe_follow_pfn(vma, start, &nums[ret]); > if (err) { > if (ret == 0) > ret = err; > diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c > b/drivers/media/v4l2-core/videobuf-dma-contig.c > index 52312ce2ba05..821c4a76ab96 100644 > --- a/drivers/media/v4l2-core/videobuf-dma-contig.c > +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c > @@ -183,7 +183,7 @@ static int videobuf_dma_contig_user_get(struct > videobuf_dma_contig_memory *mem, > user_address = untagged_baddr; > > while (pages_done < (mem->size >> PAGE_SHIFT)) { > - ret = follow_pfn(vma, user_address, &this_pfn); > + ret = unsafe_follow_pfn(vma, user_address, &this_pfn); > if (ret) > break; > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 00/15] drm/vc4: hdmi: Add CEC support for the BCM2711
On 18/01/2021 14:55, Hans Verkuil wrote: > On 12/01/2021 16:24, Hans Verkuil wrote: >> Hi Maxime, >> >> On 11/01/2021 15:22, Maxime Ripard wrote: >>> Hi, >>> >>> Here's a series introducing the CEC support for the BCM2711 found on the >>> RaspberryPi4. >>> >>> The BCM2711 HDMI controller uses a similar layout for the CEC registers, the >>> main difference being that the interrupt handling part is now shared between >>> both HDMI controllers. >>> >>> This series is mainly about fixing a couple of bugs, reworking the driver to >>> support having two different interrupts, one for each direction, provided >>> by an >>> external irqchip, and enables the irqchip driver for the controller we have. >>> >>> This has been tested on an RPi3 and RPi4, but requires the latest firmware. >>> It's is based on the 10 and 12 bpc series. >> >> Thank you for this series, I plan to test this later this week. > > Testing is delayed: my microHDMI to HDMI adapter has problems with the CEC pin > (possibly not connected at all). I've ordered adapter cables (hopefully of > better > quality), but those haven't arrived yet. I expect them later this week. After testing this you can add my: Acked-by: Hans Verkuil Tested-by: Hans Verkuil for the patches in this series. Thank you for working on this! Regards, Hans > > Regards, > > Hans > >> >> Regards, >> >> Hans >> >>> >>> Here is the cec-compliance output: >>> >>> pi@raspberrypi:~$ cec-ctl --tuner -p 1.0.0.0 >>> The CEC adapter doesn't allow setting the physical address manually, ignore >>> this option. >>> >>> Driver Info: >>> Driver Name: vc4_hdmi >>> Adapter Name : vc4 >>> Capabilities : 0x010e >>> Logical Addresses >>> Transmit >>> Passthrough >>> Driver version : 5.10.0 >>> Available Logical Addresses: 1 >>> Physical Address : 1.0.0.0 >>> Logical Address Mask : 0x0008 >>> CEC Version: 2.0 >>> Vendor ID : 0x000c03 (HDMI) >>> OSD Name : Tuner >>> Logical Addresses : 1 (Allow RC Passthrough) >>> >>> Logical Address : 3 (Tuner 1) >>> Primary Device Type: Tuner >>> Logical Address Type : Tuner >>> All Device Types : Tuner >>> RC TV Profile : None >>> Device Features: >>> None >>> >>> pi@raspberrypi:~$ cec-compliance >>> cec-compliance SHA : not available >>> Driver Info: >>> Driver Name: vc4_hdmi >>> Adapter Name : vc4 >>> Capabilities : 0x010e >>> Logical Addresses >>> Transmit >>> Passthrough >>> Driver version : 5.10.0 >>> Available Logical Addresses: 1 >>> Physical Address : 1.0.0.0 >>> Logical Address Mask : 0x0008 >>> CEC Version: 2.0 >>> Vendor ID : 0x000c03 (HDMI) >>> OSD Name : Tuner >>> Logical Addresses : 1 (Allow RC Passthrough) >>> >>> Logical Address : 3 (Tuner 1) >>> Primary Device Type: Tuner >>> Logical Address Type : Tuner >>> All Device Types : Tuner >>> RC TV Profile : None >>> Device Features: >>> None >>> >>> Compliance test for device /dev/cec0: >>> >>> The test results mean the following: >>> OK Supported correctly by the device. >>> OK (Not Supported) Not supported and not mandatory for the device. >>> OK (Presumed) Presumably supported. Manually check to >>> confirm. >>> OK (Unexpected) Supported correctly but is not expected to be >>> supported for this device. >>> OK (Refused)Supported by the device, but was refused. >>> FAILFailed and was expected to be supported by this >>> device. >>> >
Re: [PATCH v3 1/4] dp/dp_mst: Add support for sink event notify messages
Hi Lyude, Daniel referred me to you as the best person to review the MST parts of this series. I can commit this, but then I prefer to have a Reviewed-by or Acked-by from someone for the first 3 DP MST patches. Alternatively, you can take the whole series (I've reviewed the 4th CEC patch). Regards, Hans On 12/01/2021 10:24, Hans Verkuil wrote: > Hi Sam, > > This series still hasn't been merged. It still applies cleanly to v5.11-rc1. > > Daniel, can you merge this series for 5.12? Or Ack this series so I can merge > it? > > The first three patches deal with DP MST support, and this needs review from > you or David. > > Regards, > > Hans > > On 23/09/2020 04:13, Sam McNally wrote: >> Sink event notify messages are used for MST CEC IRQs. Add parsing >> support for sink event notify messages in preparation for handling MST >> CEC IRQs. >> >> Signed-off-by: Sam McNally >> --- >> >> (no changes since v1) >> >> drivers/gpu/drm/drm_dp_mst_topology.c | 37 ++- >> include/drm/drm_dp_mst_helper.h | 14 ++ >> 2 files changed, 50 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c >> b/drivers/gpu/drm/drm_dp_mst_topology.c >> index 17dbed0a9800..15b6cc39a754 100644 >> --- a/drivers/gpu/drm/drm_dp_mst_topology.c >> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c >> @@ -1027,6 +1027,30 @@ static bool >> drm_dp_sideband_parse_resource_status_notify(struct drm_dp_sideband_ >> return false; >> } >> >> +static bool drm_dp_sideband_parse_sink_event_notify( >> +struct drm_dp_sideband_msg_rx *raw, >> +struct drm_dp_sideband_msg_req_body *msg) >> +{ >> +int idx = 1; >> + >> +msg->u.sink_event.port_number = (raw->msg[idx] & 0xf0) >> 4; >> +idx++; >> +if (idx > raw->curlen) >> +goto fail_len; >> + >> +memcpy(msg->u.sink_event.guid, &raw->msg[idx], 16); >> +idx += 16; >> +if (idx > raw->curlen) >> +goto fail_len; >> + >> +msg->u.sink_event.event_id = (raw->msg[idx] << 8) | (raw->msg[idx + 1]); >> +idx++; >> +return true; >> +fail_len: >> +DRM_DEBUG_KMS("sink event notify parse length fail %d %d\n", idx, >> raw->curlen); >> +return false; >> +} >> + >> static bool drm_dp_sideband_parse_req(struct drm_dp_sideband_msg_rx *raw, >>struct drm_dp_sideband_msg_req_body *msg) >> { >> @@ -1038,6 +1062,8 @@ static bool drm_dp_sideband_parse_req(struct >> drm_dp_sideband_msg_rx *raw, >> return drm_dp_sideband_parse_connection_status_notify(raw, msg); >> case DP_RESOURCE_STATUS_NOTIFY: >> return drm_dp_sideband_parse_resource_status_notify(raw, msg); >> +case DP_SINK_EVENT_NOTIFY: >> +return drm_dp_sideband_parse_sink_event_notify(raw, msg); >> default: >> DRM_ERROR("Got unknown request 0x%02x (%s)\n", msg->req_type, >>drm_dp_mst_req_type_str(msg->req_type)); >> @@ -3875,6 +3901,8 @@ drm_dp_mst_process_up_req(struct >> drm_dp_mst_topology_mgr *mgr, >> guid = msg->u.conn_stat.guid; >> else if (msg->req_type == DP_RESOURCE_STATUS_NOTIFY) >> guid = msg->u.resource_stat.guid; >> +else if (msg->req_type == DP_SINK_EVENT_NOTIFY) >> +guid = msg->u.sink_event.guid; >> >> if (guid) >> mstb = drm_dp_get_mst_branch_device_by_guid(mgr, guid); >> @@ -3948,7 +3976,8 @@ static int drm_dp_mst_handle_up_req(struct >> drm_dp_mst_topology_mgr *mgr) >> drm_dp_sideband_parse_req(&mgr->up_req_recv, &up_req->msg); >> >> if (up_req->msg.req_type != DP_CONNECTION_STATUS_NOTIFY && >> -up_req->msg.req_type != DP_RESOURCE_STATUS_NOTIFY) { >> +up_req->msg.req_type != DP_RESOURCE_STATUS_NOTIFY && >> +up_req->msg.req_type != DP_SINK_EVENT_NOTIFY) { >> DRM_DEBUG_KMS("Received unknown up req type, ignoring: %x\n", >>up_req->msg.req_type); >> kfree(up_req); >> @@ -3976,6 +4005,12 @@ static int drm_dp_mst_handle_up_req(struct >> drm_dp_mst_topology_mgr *mgr) >> DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", >>
Re: [PATCH v3 1/4] dp/dp_mst: Add support for sink event notify messages
Hi Sam, Are you able to work on a v4? I haven't heard from you for some time now. I would be willing to take over this series if it wasn't for the fact that I do not have any hardware to test this with. Regards, Hans On 01/02/2021 22:56, Lyude Paul wrote: > On Wed, 2020-09-23 at 12:13 +1000, Sam McNally wrote: >> Sink event notify messages are used for MST CEC IRQs. Add parsing >> support for sink event notify messages in preparation for handling MST >> CEC IRQs. >> >> Signed-off-by: Sam McNally >> --- >> >> (no changes since v1) >> >> drivers/gpu/drm/drm_dp_mst_topology.c | 37 ++- >> include/drm/drm_dp_mst_helper.h | 14 ++ >> 2 files changed, 50 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c >> b/drivers/gpu/drm/drm_dp_mst_topology.c >> index 17dbed0a9800..15b6cc39a754 100644 >> --- a/drivers/gpu/drm/drm_dp_mst_topology.c >> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c >> @@ -1027,6 +1027,30 @@ static bool >> drm_dp_sideband_parse_resource_status_notify(struct drm_dp_sideband_ >> return false; >> } >> >> +static bool drm_dp_sideband_parse_sink_event_notify( >> + struct drm_dp_sideband_msg_rx *raw, >> + struct drm_dp_sideband_msg_req_body *msg) >> +{ >> + int idx = 1; >> + >> + msg->u.sink_event.port_number = (raw->msg[idx] & 0xf0) >> 4; >> + idx++; >> + if (idx > raw->curlen) >> + goto fail_len; >> + >> + memcpy(msg->u.sink_event.guid, &raw->msg[idx], 16); >> + idx += 16; >> + if (idx > raw->curlen) >> + goto fail_len; >> + >> + msg->u.sink_event.event_id = (raw->msg[idx] << 8) | (raw->msg[idx + >> 1]); >> + idx++; >> + return true; >> +fail_len: >> + DRM_DEBUG_KMS("sink event notify parse length fail %d %d\n", idx, >> raw- >>> curlen); > > Is it possible for us to use drm_dbg_kms() here? > > Also-there is an MST selftest you should update for this > >> + return false; >> +} >> + >> static bool drm_dp_sideband_parse_req(struct drm_dp_sideband_msg_rx *raw, >> struct drm_dp_sideband_msg_req_body >> *msg) >> { >> @@ -1038,6 +1062,8 @@ static bool drm_dp_sideband_parse_req(struct >> drm_dp_sideband_msg_rx *raw, >> return drm_dp_sideband_parse_connection_status_notify(raw, >> msg); >> case DP_RESOURCE_STATUS_NOTIFY: >> return drm_dp_sideband_parse_resource_status_notify(raw, >> msg); >> + case DP_SINK_EVENT_NOTIFY: >> + return drm_dp_sideband_parse_sink_event_notify(raw, msg); >> default: >> DRM_ERROR("Got unknown request 0x%02x (%s)\n", msg->req_type, >> drm_dp_mst_req_type_str(msg->req_type)); >> @@ -3875,6 +3901,8 @@ drm_dp_mst_process_up_req(struct >> drm_dp_mst_topology_mgr >> *mgr, >> guid = msg->u.conn_stat.guid; >> else if (msg->req_type == DP_RESOURCE_STATUS_NOTIFY) >> guid = msg->u.resource_stat.guid; >> + else if (msg->req_type == DP_SINK_EVENT_NOTIFY) >> + guid = msg->u.sink_event.guid; >> >> if (guid) >> mstb = drm_dp_get_mst_branch_device_by_guid(mgr, >> guid); >> @@ -3948,7 +3976,8 @@ static int drm_dp_mst_handle_up_req(struct >> drm_dp_mst_topology_mgr *mgr) >> drm_dp_sideband_parse_req(&mgr->up_req_recv, &up_req->msg); >> >> if (up_req->msg.req_type != DP_CONNECTION_STATUS_NOTIFY && >> - up_req->msg.req_type != DP_RESOURCE_STATUS_NOTIFY) { >> + up_req->msg.req_type != DP_RESOURCE_STATUS_NOTIFY && >> + up_req->msg.req_type != DP_SINK_EVENT_NOTIFY) { >> DRM_DEBUG_KMS("Received unknown up req type, ignoring: %x\n", >> up_req->msg.req_type); >> kfree(up_req); >> @@ -3976,6 +4005,12 @@ static int drm_dp_mst_handle_up_req(struct >> drm_dp_mst_topology_mgr *mgr) >> DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", >> res_stat->port_number, >> res_stat->available_pbn); >> + } else if (up_req->msg.req_type == DP_SINK_EVENT_NOTIFY) { >> + const struct drm_dp_sink_event_notify *sink_event = >> + &up_req->msg.u.sink_event; >> + >> + DRM_DEBUG_KMS("Got SEN: pn: %d event_id %d\n", >> + sink_event->port_number, sink_event->event_id); >> } >> >> up_req->hdr = mgr->up_req_recv.initial_hdr; >> diff --git a/include/drm/drm_dp_mst_helper.h >> b/include/drm/drm_dp_mst_helper.h >> index 6ae5860d8644..c7c79e0ced18 100644 >> --- a/include/drm/drm_dp_mst_helper.h >> +++ b/include/drm/drm_dp_mst_helper.h >> @@ -402,6 +402,19 @@ struct drm_dp_resource_status_notify { >> u16 available_pbn; >> }; >> >> +#define DP_SINK_EVENT_
Re: [PATCH v3 2/4] drm_dp_mst_topology: use correct AUX channel
On 01/02/2021 23:13, Ville Syrjälä wrote: > On Wed, Sep 23, 2020 at 12:13:53PM +1000, Sam McNally wrote: >> From: Hans Verkuil >> >> For adapters behind an MST hub use the correct AUX channel. >> >> Signed-off-by: Hans Verkuil >> [sa...@chromium.org: rebased, removing redundant changes] >> Signed-off-by: Sam McNally >> --- >> >> (no changes since v1) >> >> drivers/gpu/drm/drm_dp_mst_topology.c | 36 +++ >> 1 file changed, 36 insertions(+) >> >> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c >> b/drivers/gpu/drm/drm_dp_mst_topology.c >> index 15b6cc39a754..0d753201adbd 100644 >> --- a/drivers/gpu/drm/drm_dp_mst_topology.c >> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c >> @@ -2255,6 +2255,9 @@ drm_dp_mst_topology_unlink_port(struct >> drm_dp_mst_topology_mgr *mgr, >> drm_dp_mst_topology_put_port(port); >> } >> >> +static ssize_t >> +drm_dp_mst_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg); >> + >> static struct drm_dp_mst_port * >> drm_dp_mst_add_port(struct drm_device *dev, >> struct drm_dp_mst_topology_mgr *mgr, >> @@ -2271,9 +2274,13 @@ drm_dp_mst_add_port(struct drm_device *dev, >> port->port_num = port_number; >> port->mgr = mgr; >> port->aux.name = "DPMST"; >> +mutex_init(&port->aux.hw_mutex); >> +mutex_init(&port->aux.cec.lock); >> port->aux.dev = dev->dev; >> port->aux.is_remote = true; >> >> +port->aux.transfer = drm_dp_mst_aux_transfer; >> + > > This was supposed to be handled via higher levels checking for > is_remote==true. Ah, I suspect this patch can be dropped entirely: it predates commit 2f221a5efed4 ("drm/dp_mst: Add MST support to DP DPCD R/W functions"). It looks like that commit basically solved what this older patch attempts to do as well. Sam, can you test if it works without this patch? Regards, Hans > >> /* initialize the MST downstream port's AUX crc work queue */ >> drm_dp_remote_aux_init(&port->aux); >> >> @@ -3503,6 +3510,35 @@ static int drm_dp_send_up_ack_reply(struct >> drm_dp_mst_topology_mgr *mgr, >> return 0; >> } >> >> +static ssize_t >> +drm_dp_mst_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) >> +{ >> +struct drm_dp_mst_port *port = >> +container_of(aux, struct drm_dp_mst_port, aux); >> +int ret; >> + >> +switch (msg->request & ~DP_AUX_I2C_MOT) { >> +case DP_AUX_NATIVE_WRITE: >> +case DP_AUX_I2C_WRITE: >> +case DP_AUX_I2C_WRITE_STATUS_UPDATE: >> +ret = drm_dp_send_dpcd_write(port->mgr, port, msg->address, >> + msg->size, msg->buffer); > > That doesn't make sense to me. I2c writes and DPCD writes > are definitely not the same thing. > > aux->transfer is a very low level thing. I don't think it's the > correct level of abstraction for sideband. > >> +break; >> + >> +case DP_AUX_NATIVE_READ: >> +case DP_AUX_I2C_READ: >> +ret = drm_dp_send_dpcd_read(port->mgr, port, msg->address, >> +msg->size, msg->buffer); >> +break; >> + >> +default: >> +ret = -EINVAL; >> +break; >> +} >> + >> +return ret; >> +} >> + >> static int drm_dp_get_vc_payload_bw(u8 dp_link_bw, u8 dp_link_count) >> { >> if (dp_link_bw == 0 || dp_link_count == 0) >> -- >> 2.28.0.681.g6f77f65b4e-goog >> >> ___ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 4/4] drm_dp_cec: add MST support
On 23/09/2020 04:13, Sam McNally wrote: > With DP v2.0 errata E5, CEC tunneling can be supported through an MST > topology. > > There are some minor differences for CEC tunneling through an MST > topology compared to CEC tunneling to an SST port: > - CEC IRQs are delivered via a sink event notify message > - CEC-related DPCD registers are accessed via remote DPCD reads and > writes. > > This results in the MST implementation diverging from the existing SST > implementation: > - sink event notify messages with CEC_IRQ ID set indicate CEC IRQ rather > than ESI1 > - setting edid and handling CEC IRQs, which can be triggered from > contexts where locks held preclude HPD handling, are deferred to avoid > remote DPCD access which would block until HPD handling is performed > or a timeout > > Register and unregister for all MST connectors, ensuring their > drm_dp_aux_cec struct won't be accessed uninitialized. > > Reviewed-by: Hans Verkuil > Signed-off-by: Sam McNally > --- > > Changes in v3: > - Fixed whitespace in drm_dp_cec_mst_irq_work() > - Moved drm_dp_cec_mst_set_edid_work() with the other set_edid functions > > Changes in v2: > - Used aux->is_remote instead of aux->cec.is_mst, removing the need for > the previous patch in the series > - Added a defensive check for null edid in the deferred set_edid work, > in case the edid is no longer valid at that point > > drivers/gpu/drm/drm_dp_cec.c | 68 +-- > drivers/gpu/drm/drm_dp_mst_topology.c | 24 ++ > include/drm/drm_dp_helper.h | 4 ++ > 3 files changed, 91 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c > index 3ab2609f9ec7..1020b2cffdf0 100644 > --- a/drivers/gpu/drm/drm_dp_cec.c > +++ b/drivers/gpu/drm/drm_dp_cec.c > @@ -14,6 +14,7 @@ > #include > #include > #include > +#include > > /* > * Unfortunately it turns out that we have a chicken-and-egg situation > @@ -248,6 +249,10 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux) > if (!aux->transfer) > return; > > + if (aux->is_remote) { > + schedule_work(&aux->cec.mst_irq_work); > + return; > + } Are these workqueues for cec_irq and cec_set_edid actually needed? They are called directly from drm_dp_mst_topology.c, and I think they can be handled identically to a normal, non-remote, aux device. Avoiding using a workqueue probably also means that there is no need for exporting drm_dp_mst_topology_get_port_validated and drm_dp_mst_topology_put_port. Provided that I am not missing something, this should simplify the code quite a bit. Regards, Hans > mutex_lock(&aux->cec.lock); > if (!aux->cec.adap) > goto unlock; > @@ -276,6 +281,23 @@ static bool drm_dp_cec_cap(struct drm_dp_aux *aux, u8 > *cec_cap) > return true; > } > > +static void drm_dp_cec_mst_irq_work(struct work_struct *work) > +{ > + struct drm_dp_aux *aux = container_of(work, struct drm_dp_aux, > + cec.mst_irq_work); > + struct drm_dp_mst_port *port = > + container_of(aux, struct drm_dp_mst_port, aux); > + > + port = drm_dp_mst_topology_get_port_validated(port->mgr, port); > + if (!port) > + return; > + mutex_lock(&aux->cec.lock); > + if (aux->cec.adap) > + drm_dp_cec_handle_irq(aux); > + mutex_unlock(&aux->cec.lock); > + drm_dp_mst_topology_put_port(port); > +} > + > /* > * Called if the HPD was low for more than drm_dp_cec_unregister_delay > * seconds. This unregisters the CEC adapter. > @@ -297,7 +319,8 @@ static void drm_dp_cec_unregister_work(struct work_struct > *work) > * were unchanged and just update the CEC physical address. Otherwise > * unregister the old CEC adapter and create a new one. > */ > -void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) > +static void drm_dp_cec_handle_set_edid(struct drm_dp_aux *aux, > +const struct edid *edid) > { > struct drm_connector *connector = aux->cec.connector; > u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD | > @@ -306,10 +329,6 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const > struct edid *edid) > unsigned int num_las = 1; > u8 cap; > > - /* No transfer function was set, so not a DP connector */ > - if (!aux->transfer) > - return; > - > #ifndef CONFIG_MEDIA_CEC_RC > /* >* CEC_CAP_RC is part of CEC_CAP_DEFAULTS,
Re: [PATCH v3 1/4] dp/dp_mst: Add support for sink event notify messages
Hi Sam, I replied to several of the patches: it looks like the drm code has changed since some of this patches were written, and I think it can be simplified quite a bit. Regards, Hans On 04/02/2021 10:54, Sam McNally wrote: > I can for this patch; I'm not really sure of the right approach for the other > two though. > > On Wed, 3 Feb 2021 at 20:57, Hans Verkuil <mailto:hverk...@xs4all.nl>> wrote: > > Hi Sam, > > Are you able to work on a v4? > > I haven't heard from you for some time now. I would be willing to take > over > this series if it wasn't for the fact that I do not have any hardware to > test > this with. > > Regards, > > Hans > > On 01/02/2021 22:56, Lyude Paul wrote: > > On Wed, 2020-09-23 at 12:13 +1000, Sam McNally wrote: > >> Sink event notify messages are used for MST CEC IRQs. Add parsing > >> support for sink event notify messages in preparation for handling MST > >> CEC IRQs. > >> > >> Signed-off-by: Sam McNally <mailto:sa...@chromium.org>> > >> --- > >> > >> (no changes since v1) > >> > >> drivers/gpu/drm/drm_dp_mst_topology.c | 37 ++- > >> include/drm/drm_dp_mst_helper.h | 14 ++ > >> 2 files changed, 50 insertions(+), 1 deletion(-) > >> > >> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c > >> b/drivers/gpu/drm/drm_dp_mst_topology.c > >> index 17dbed0a9800..15b6cc39a754 100644 > >> --- a/drivers/gpu/drm/drm_dp_mst_topology.c > >> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c > >> @@ -1027,6 +1027,30 @@ static bool > >> drm_dp_sideband_parse_resource_status_notify(struct drm_dp_sideband_ > >> return false; > >> } > >> > >> +static bool drm_dp_sideband_parse_sink_event_notify( > >> + struct drm_dp_sideband_msg_rx *raw, > >> + struct drm_dp_sideband_msg_req_body *msg) > >> +{ > >> + int idx = 1; > >> + > >> + msg->u.sink_event.port_number = (raw->msg[idx] & 0xf0) >> 4; > >> + idx++; > >> + if (idx > raw->curlen) > >> + goto fail_len; > >> + > >> + memcpy(msg->u.sink_event.guid, &raw->msg[idx], 16); > >> + idx += 16; > >> + if (idx > raw->curlen) > >> + goto fail_len; > >> + > >> + msg->u.sink_event.event_id = (raw->msg[idx] << 8) | > (raw->msg[idx + > >> 1]); > >> + idx++; > >> + return true; > >> +fail_len: > >> + DRM_DEBUG_KMS("sink event notify parse length fail %d %d\n", > idx, raw- > >>> curlen); > > > > Is it possible for us to use drm_dbg_kms() here? > > > > Also-there is an MST selftest you should update for this > > > >> + return false; > >> +} > >> + > >> static bool drm_dp_sideband_parse_req(struct drm_dp_sideband_msg_rx > *raw, > >> struct > drm_dp_sideband_msg_req_body > >> *msg) > >> { > >> @@ -1038,6 +1062,8 @@ static bool drm_dp_sideband_parse_req(struct > >> drm_dp_sideband_msg_rx *raw, > >> return > drm_dp_sideband_parse_connection_status_notify(raw, > >> msg); > >> case DP_RESOURCE_STATUS_NOTIFY: > >> return > drm_dp_sideband_parse_resource_status_notify(raw, msg); > >> + case DP_SINK_EVENT_NOTIFY: > >> + return drm_dp_sideband_parse_sink_event_notify(raw, > msg); > >> default: > >> DRM_ERROR("Got unknown request 0x%02x (%s)\n", > msg->req_type, > >> drm_dp_mst_req_type_str(msg->req_type)); > >> @@ -3875,6 +3901,8 @@ drm_dp_mst_process_up_req(struct > drm_dp_mst_topology_mgr > >> *mgr, > >> guid = msg->u.conn_stat.guid; > >> else if (msg->req_type == DP_RESOURCE_STATUS_NOTIFY) > >> guid = msg->u.resource_stat.guid; > >> + else if (msg->req_type
Re: [PATCH v3 2/4] drm_dp_mst_topology: use correct AUX channel
On 05/02/2021 14:24, Ville Syrjälä wrote: > On Fri, Feb 05, 2021 at 04:17:51PM +1100, Sam McNally wrote: >> On Thu, 4 Feb 2021 at 21:19, Hans Verkuil wrote: >>> >>> On 01/02/2021 23:13, Ville Syrjälä wrote: >>>> On Wed, Sep 23, 2020 at 12:13:53PM +1000, Sam McNally wrote: >>>>> From: Hans Verkuil >>>>> >>>>> For adapters behind an MST hub use the correct AUX channel. >>>>> >>>>> Signed-off-by: Hans Verkuil >>>>> [sa...@chromium.org: rebased, removing redundant changes] >>>>> Signed-off-by: Sam McNally >>>>> --- >>>>> >>>>> (no changes since v1) >>>>> >>>>> drivers/gpu/drm/drm_dp_mst_topology.c | 36 +++ >>>>> 1 file changed, 36 insertions(+) >>>>> >>>>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c >>>>> b/drivers/gpu/drm/drm_dp_mst_topology.c >>>>> index 15b6cc39a754..0d753201adbd 100644 >>>>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c >>>>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c >>>>> @@ -2255,6 +2255,9 @@ drm_dp_mst_topology_unlink_port(struct >>>>> drm_dp_mst_topology_mgr *mgr, >>>>> drm_dp_mst_topology_put_port(port); >>>>> } >>>>> >>>>> +static ssize_t >>>>> +drm_dp_mst_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg >>>>> *msg); >>>>> + >>>>> static struct drm_dp_mst_port * >>>>> drm_dp_mst_add_port(struct drm_device *dev, >>>>> struct drm_dp_mst_topology_mgr *mgr, >>>>> @@ -2271,9 +2274,13 @@ drm_dp_mst_add_port(struct drm_device *dev, >>>>> port->port_num = port_number; >>>>> port->mgr = mgr; >>>>> port->aux.name = "DPMST"; >>>>> +mutex_init(&port->aux.hw_mutex); >>>>> +mutex_init(&port->aux.cec.lock); >>>>> port->aux.dev = dev->dev; >>>>> port->aux.is_remote = true; >>>>> >>>>> +port->aux.transfer = drm_dp_mst_aux_transfer; >>>>> + >>>> >>>> This was supposed to be handled via higher levels checking for >>>> is_remote==true. >>> >>> Ah, I suspect this patch can be dropped entirely: it predates commit >>> 2f221a5efed4 >>> ("drm/dp_mst: Add MST support to DP DPCD R/W functions"). >>> >>> It looks like that commit basically solved what this older patch attempts >>> to do >>> as well. >>> >>> Sam, can you test if it works without this patch? >> >> It almost just works; drm_dp_cec uses whether aux.transfer is non-null >> to filter out non-DP connectors. Using aux.is_remote as another signal >> indicating a DP connector seems plausible. We can drop this patch. > > Why would anyone even call this stuff on a non-DP connector? > And where did they even get the struct drm_dp_aux to do so? This check came in with commit 5ce70c799ac2 ("drm_dp_cec: check that aux has a transfer function"). It seems nouveau and amdgpu specific. A better approach would be to fix those drivers to only call these cec functions for DP outputs. I think I moved the test to drm_dp_cec.c primarily for robustness (i.e. do nothing if called for a non-DP output). But that might not be the right approach after all. Regards, Hans > >> Thanks all! >>> >>> Regards, >>> >>> Hans >>> >>>> >>>>> /* initialize the MST downstream port's AUX crc work queue */ >>>>> drm_dp_remote_aux_init(&port->aux); >>>>> >>>>> @@ -3503,6 +3510,35 @@ static int drm_dp_send_up_ack_reply(struct >>>>> drm_dp_mst_topology_mgr *mgr, >>>>> return 0; >>>>> } >>>>> >>>>> +static ssize_t >>>>> +drm_dp_mst_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg >>>>> *msg) >>>>> +{ >>>>> +struct drm_dp_mst_port *port = >>>>> +container_of(aux, struct drm_dp_mst_port, aux); >>>>> +int ret; >>>>> + >>>>> +switch (msg->request & ~DP_AUX_I2C_MOT) { >>>>> +case DP_AUX_NATIVE_WRITE: >>>>> +case DP_AUX_I2C_WRITE: >>>>> +case DP_AUX
[PATCH 4/5] drm/omap: hdmi5: add CEC support
Add HDMI CEC support for OMAP5. Many thanks to Tomi for helping out how to enable CEC for omap5. Signed-off-by: Hans Verkuil Thanks-to: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/Kconfig | 8 + drivers/gpu/drm/omapdrm/dss/Makefile | 1 + drivers/gpu/drm/omapdrm/dss/hdmi.h | 1 + drivers/gpu/drm/omapdrm/dss/hdmi5.c | 63 +-- drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c | 201 +++ drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h | 42 + drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 28 +++- drivers/gpu/drm/omapdrm/dss/hdmi5_core.h | 33 +++- 8 files changed, 358 insertions(+), 19 deletions(-) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig index e11b258a2294..67a1ba14703b 100644 --- a/drivers/gpu/drm/omapdrm/dss/Kconfig +++ b/drivers/gpu/drm/omapdrm/dss/Kconfig @@ -83,6 +83,14 @@ config OMAP5_DSS_HDMI Definition Multimedia Interface. See https://www.hdmi.org/ for HDMI specification. +config OMAP5_DSS_HDMI_CEC + bool "Enable HDMI CEC support for OMAP5" + depends on OMAP5_DSS_HDMI + select CEC_CORE + default y + help + When selected the HDMI transmitter will support the CEC feature. + config OMAP2_DSS_SDI bool "SDI support" default n diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile index f967e6948f2e..94fe0fa3b3c2 100644 --- a/drivers/gpu/drm/omapdrm/dss/Makefile +++ b/drivers/gpu/drm/omapdrm/dss/Makefile @@ -17,4 +17,5 @@ omapdss-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += hdmi_common.o hdmi_wp.o hdmi_pll.o \ omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi4_core.o omapdss-$(CONFIG_OMAP4_DSS_HDMI_CEC) += hdmi4_cec.o omapdss-$(CONFIG_OMAP5_DSS_HDMI) += hdmi5.o hdmi5_core.o +omapdss-$(CONFIG_OMAP5_DSS_HDMI_CEC) += hdmi5_cec.o ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h index c4a4e07f0b99..72d8ae441da6 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h @@ -261,6 +261,7 @@ struct hdmi_core_data { struct hdmi_wp_data *wp; unsigned int core_pwr_cnt; struct cec_adapter *adap; + struct clk *cec_clk; }; static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 54e5cb5aa52d..b674d8ba173f 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -29,12 +29,14 @@ #include #include #include +#include #include #include #include "omapdss.h" #include "hdmi5_core.h" +#include "hdmi5_cec.h" #include "dss.h" static int hdmi_runtime_get(struct omap_hdmi *hdmi) @@ -104,6 +106,10 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); } + if (irqstatus & HDMI_IRQ_CORE) { + hdmi5_cec_irq(&hdmi->core); + hdmi5_core_handle_irqs(&hdmi->core); + } return IRQ_HANDLED; } @@ -112,9 +118,12 @@ static int hdmi_power_on_core(struct omap_hdmi *hdmi) { int r; + if (hdmi->core.core_pwr_cnt++) + return 0; + r = regulator_enable(hdmi->vdda_reg); if (r) - return r; + goto err_reg_enable; r = hdmi_runtime_get(hdmi); if (r) @@ -129,12 +138,17 @@ static int hdmi_power_on_core(struct omap_hdmi *hdmi) err_runtime_get: regulator_disable(hdmi->vdda_reg); +err_reg_enable: + hdmi->core.core_pwr_cnt--; return r; } static void hdmi_power_off_core(struct omap_hdmi *hdmi) { + if (--hdmi->core.core_pwr_cnt) + return; + hdmi->core_enabled = false; hdmi_runtime_put(hdmi); @@ -168,7 +182,7 @@ static int hdmi_power_on_full(struct omap_hdmi *hdmi) pc, &hdmi_cinfo); /* disable and clear irqs */ - hdmi_wp_clear_irqenable(&hdmi->wp, 0x); + hdmi_wp_clear_irqenable(&hdmi->wp, ~HDMI_IRQ_CORE); hdmi_wp_set_irqstatus(&hdmi->wp, hdmi_wp_get_irqstatus(&hdmi->wp)); @@ -225,7 +239,7 @@ static int hdmi_power_on_full(struct omap_hdmi *hdmi) static void hdmi_power_off_full(struct omap_hdmi *hdmi) { - hdmi_wp_clear_irqenable(&hdmi->wp, 0x); + hdmi_wp_clear_irqenable(&hdmi->wp, ~HDMI_IRQ_CORE); hdmi_wp_video_stop(&hdmi->wp); @@ -273,11 +287,11 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd) REG_FLD_MOD(hd->
[PATCH 3/5] drm/omap: hdmi4: simplify CEC Phys Addr handling
Switch to using cec_s_phys_addr_from_edid() instead of a two-step process of calling cec_get_edid_phys_addr() followed by cec_s_phys_addr(). Signed-off-by: Hans Verkuil --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 13 ++--- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 4 ++-- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 5 +++-- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 765379380d4b..ac142f870109 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -432,7 +432,7 @@ static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge, struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); if (status == connector_status_disconnected) - hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID); + hdmi4_cec_set_phys_addr(&hdmi->core, NULL); } static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, @@ -440,7 +440,6 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, { struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); struct edid *edid = NULL; - unsigned int cec_addr; bool need_enable; int r; @@ -466,15 +465,7 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, hdmi_runtime_put(hdmi); mutex_unlock(&hdmi->lock); - if (edid && edid->extensions) { - unsigned int len = (edid->extensions + 1) * EDID_LENGTH; - - cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL); - } else { - cec_addr = CEC_PHYS_ADDR_INVALID; - } - - hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr); + hdmi4_cec_set_phys_addr(&hdmi->core, edid); if (need_enable) hdmi4_core_disable(&hdmi->core); diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 64f5ccd0f11b..68b4c84e1864 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -329,9 +329,9 @@ static const struct cec_adap_ops hdmi_cec_adap_ops = { .adap_transmit = hdmi_cec_adap_transmit, }; -void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) +void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, struct edid *edid) { - cec_s_phys_addr(core->adap, pa, false); + cec_s_phys_addr_from_edid(core->adap, edid); } int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h index b59a54c3040e..16bf259643b7 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h @@ -26,13 +26,14 @@ struct platform_device; /* HDMI CEC funcs */ #ifdef CONFIG_OMAP4_DSS_HDMI_CEC -void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa); +void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, struct edid *edid); void hdmi4_cec_irq(struct hdmi_core_data *core); int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, struct hdmi_wp_data *wp, struct drm_connector *conn); void hdmi4_cec_uninit(struct hdmi_core_data *core); #else -static inline void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) +static inline void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, + struct edid *edid) { } -- 2.30.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 5/5] ARM: dts: dra7/omap5: add cec clock
Add cec clock to the dra7 and omap5 device trees. Signed-off-by: Hans Verkuil --- arch/arm/boot/dts/dra7.dtsi | 5 +++-- arch/arm/boot/dts/omap5.dtsi | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index ce1194744f84..efe579ddb324 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -879,8 +879,9 @@ hdmi: encoder@0 { interrupts = ; status = "disabled"; clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>, -<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; +<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>, +<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "sys_clk", "cec"; dmas = <&sdma_xbar 76>; dma-names = "audio_tx"; }; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 5f1a8bd13880..2bb1000aeae9 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -580,8 +580,9 @@ hdmi: encoder@0 { interrupts = ; status = "disabled"; clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 9>, -<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; +<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>, +<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "sys_clk", "cec"; dmas = <&sdma 76>; dma-names = "audio_tx"; }; -- 2.30.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/5] drm/omap: hdmi4: switch to the cec bridge ops
Implement the new CEC bridge ops. This makes it possible to associate a CEC adapter with a drm connector, which helps userspace determine with cec device node belongs to which drm connector. Signed-off-by: Hans Verkuil --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 28 + drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 8 --- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 7 --- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 8de41e74e8f8..765379380d4b 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -482,6 +482,21 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, return edid; } +static int hdmi4_bridge_cec_init(struct drm_bridge *bridge, +struct drm_connector *conn) +{ + struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); + + return hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp, conn); +} + +static void hdmi4_bridge_cec_exit(struct drm_bridge *bridge) +{ + struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); + + hdmi4_cec_uninit(&hdmi->core); +} + static const struct drm_bridge_funcs hdmi4_bridge_funcs = { .attach = hdmi4_bridge_attach, .mode_set = hdmi4_bridge_mode_set, @@ -492,13 +507,15 @@ static const struct drm_bridge_funcs hdmi4_bridge_funcs = { .atomic_disable = hdmi4_bridge_disable, .hpd_notify = hdmi4_bridge_hpd_notify, .get_edid = hdmi4_bridge_get_edid, + .cec_init = hdmi4_bridge_cec_init, + .cec_exit = hdmi4_bridge_cec_exit, }; static void hdmi4_bridge_init(struct omap_hdmi *hdmi) { hdmi->bridge.funcs = &hdmi4_bridge_funcs; hdmi->bridge.of_node = hdmi->pdev->dev.of_node; - hdmi->bridge.ops = DRM_BRIDGE_OP_EDID; + hdmi->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_CEC; hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; drm_bridge_add(&hdmi->bridge); @@ -647,14 +664,10 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data) if (r) goto err_runtime_put; - r = hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp); - if (r) - goto err_pll_uninit; - r = hdmi_audio_register(hdmi); if (r) { DSSERR("Registering HDMI audio failed\n"); - goto err_cec_uninit; + goto err_pll_uninit; } hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs, @@ -664,8 +677,6 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data) return 0; -err_cec_uninit: - hdmi4_cec_uninit(&hdmi->core); err_pll_uninit: hdmi_pll_uninit(&hdmi->pll); err_runtime_put: @@ -682,7 +693,6 @@ static void hdmi4_unbind(struct device *dev, struct device *master, void *data) if (hdmi->audio_pdev) platform_device_unregister(hdmi->audio_pdev); - hdmi4_cec_uninit(&hdmi->core); hdmi_pll_uninit(&hdmi->pll); } diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 43592c1cf081..64f5ccd0f11b 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -335,10 +335,10 @@ void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) } int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, - struct hdmi_wp_data *wp) + struct hdmi_wp_data *wp, struct drm_connector *conn) { - const u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | -CEC_CAP_PASSTHROUGH | CEC_CAP_RC; + const u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO; + struct cec_connector_info conn_info; int ret; core->adap = cec_allocate_adapter(&hdmi_cec_adap_ops, core, @@ -346,6 +346,8 @@ int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, ret = PTR_ERR_OR_ZERO(core->adap); if (ret < 0) return ret; + cec_fill_conn_info_from_drm(&conn_info, conn); + cec_s_conn_info(core->adap, &conn_info); core->wp = wp; /* Disable clock initially, hdmi_cec_adap_enable() manages it */ diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h index 0292337c97cc..b59a54c3040e 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h @@ -29,7 +29,7 @@ struct platform_device; void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa); void hdmi4_cec_irq(struct hdmi_core_data *core); int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, -
[PATCH 1/5] drm: drm_bridge: add cec_init/exit bridge ops
Add bridge cec_init/exit ops. These ops will be responsible for creating and destroying the CEC adapter for the bridge that supports CEC. Signed-off-by: Hans Verkuil --- drivers/gpu/drm/drm_bridge_connector.c | 23 +++ include/drm/drm_bridge.h | 31 ++ 2 files changed, 54 insertions(+) diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index 791379816837..2ff90f5e468c 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -84,6 +84,13 @@ struct drm_bridge_connector { * connector modes detection, if any (see &DRM_BRIDGE_OP_MODES). */ struct drm_bridge *bridge_modes; + /** +* @bridge_cec: +* +* The last bridge in the chain (closest to the connector) that provides +* cec adapter support, if any (see &DRM_BRIDGE_OP_CEC). +*/ + struct drm_bridge *bridge_cec; }; #define to_drm_bridge_connector(x) \ @@ -204,6 +211,11 @@ static void drm_bridge_connector_destroy(struct drm_connector *connector) struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); + if (bridge_connector->bridge_cec) { + struct drm_bridge *cec = bridge_connector->bridge_cec; + + cec->funcs->cec_exit(cec); + } if (bridge_connector->bridge_hpd) { struct drm_bridge *hpd = bridge_connector->bridge_hpd; @@ -352,6 +364,8 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, bridge_connector->bridge_detect = bridge; if (bridge->ops & DRM_BRIDGE_OP_MODES) bridge_connector->bridge_modes = bridge; + if (bridge->ops & DRM_BRIDGE_OP_CEC) + bridge_connector->bridge_cec = bridge; if (!drm_bridge_get_next_bridge(bridge)) connector_type = bridge->type; @@ -374,6 +388,15 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, else if (bridge_connector->bridge_detect) connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + if (bridge_connector->bridge_cec) { + struct drm_bridge *bridge = bridge_connector->bridge_cec; + int ret = bridge->funcs->cec_init(bridge, connector); + + if (ret) { + drm_bridge_connector_destroy(connector); + return ERR_PTR(ret); + } + } return connector; } diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 2195daa289d2..4c83c2657e87 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -629,6 +629,30 @@ struct drm_bridge_funcs { * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops. */ void (*hpd_disable)(struct drm_bridge *bridge); + + /** +* @cec_init: +* +* Initialize the CEC adapter. +* +* This callback is optional and shall only be implemented by bridges +* that support a CEC adapter. Bridges that implement it shall also +* implement the @cec_exit callback and set the DRM_BRIDGE_OP_CEC flag +* in their &drm_bridge->ops. +*/ + int (*cec_init)(struct drm_bridge *bridge, struct drm_connector *conn); + + /** +* @cec_exit: +* +* Terminate the CEC adapter. +* +* This callback is optional and shall only be implemented by bridges +* that support a CEC adapter. Bridges that implement it shall also +* implement the @cec_init callback and set the DRM_BRIDGE_OP_CEC flag +* in their &drm_bridge->ops. +*/ + void (*cec_exit)(struct drm_bridge *bridge); }; /** @@ -698,6 +722,13 @@ enum drm_bridge_ops { * this flag shall implement the &drm_bridge_funcs->get_modes callback. */ DRM_BRIDGE_OP_MODES = BIT(3), + /** +* @DRM_BRIDGE_OP_CEC: The bridge supports a CEC adapter. +* Bridges that set this flag shall implement the +* &drm_bridge_funcs->cec_init and &drm_bridge_funcs->cec_exit +* callbacks. +*/ + DRM_BRIDGE_OP_CEC = BIT(4), }; /** -- 2.30.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/5] drm/omap: hdmi: improve hdmi4 CEC, add CEC for hdmi5
This series improves the drm_bridge support for CEC by introducing two new bridge ops in the first patch, and using those in the second patch. This makes it possible to call cec_s_conn_info() and set CEC_CAP_CONNECTOR_INFO for the CEC adapter, so userspace can associate the CEC adapter with the corresponding DRM connector. The third patch simplifies CEC physical address handling by using the cec_s_phys_addr_from_edid helper function that didn't exist when this code was originally written. The fourth patch adds CEC support to the OMAP5 driver and the last patch adds the missing cec clock to the dra7 and omap5 device tree. Tested with a Pandaboard and a Beagle X15 board. Regards, Hans Hans Verkuil (5): drm: drm_bridge: add cec_init/exit bridge ops drm/omap: hdmi4: switch to the cec bridge ops drm/omap: hdmi4: simplify CEC Phys Addr handling drm/omap: hdmi5: add CEC support ARM: dts: dra7/omap5: add cec clock arch/arm/boot/dts/dra7.dtsi | 5 +- arch/arm/boot/dts/omap5.dtsi | 5 +- drivers/gpu/drm/drm_bridge_connector.c | 23 +++ drivers/gpu/drm/omapdrm/dss/Kconfig | 8 + drivers/gpu/drm/omapdrm/dss/Makefile | 1 + drivers/gpu/drm/omapdrm/dss/hdmi.h | 1 + drivers/gpu/drm/omapdrm/dss/hdmi4.c | 41 ++--- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 12 +- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 12 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 63 +-- drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c | 201 +++ drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h | 42 + drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 28 +++- drivers/gpu/drm/omapdrm/dss/hdmi5_core.h | 33 +++- include/drm/drm_bridge.h | 31 15 files changed, 453 insertions(+), 53 deletions(-) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h -- 2.30.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/5] drm: drm_bridge: add cec_init/exit bridge ops
On 19/02/2021 13:02, Laurent Pinchart wrote: > Hi Hans, > > Thank you for the patch. > > On Thu, Feb 11, 2021 at 11:36:59AM +0100, Hans Verkuil wrote: >> Add bridge cec_init/exit ops. These ops will be responsible for >> creating and destroying the CEC adapter for the bridge that supports >> CEC. >> >> Signed-off-by: Hans Verkuil >> --- >> drivers/gpu/drm/drm_bridge_connector.c | 23 +++ >> include/drm/drm_bridge.h | 31 ++ >> 2 files changed, 54 insertions(+) >> >> diff --git a/drivers/gpu/drm/drm_bridge_connector.c >> b/drivers/gpu/drm/drm_bridge_connector.c >> index 791379816837..2ff90f5e468c 100644 >> --- a/drivers/gpu/drm/drm_bridge_connector.c >> +++ b/drivers/gpu/drm/drm_bridge_connector.c >> @@ -84,6 +84,13 @@ struct drm_bridge_connector { >> * connector modes detection, if any (see &DRM_BRIDGE_OP_MODES). >> */ >> struct drm_bridge *bridge_modes; >> +/** >> + * @bridge_cec: >> + * >> + * The last bridge in the chain (closest to the connector) that provides >> + * cec adapter support, if any (see &DRM_BRIDGE_OP_CEC). >> + */ >> +struct drm_bridge *bridge_cec; >> }; >> >> #define to_drm_bridge_connector(x) \ >> @@ -204,6 +211,11 @@ static void drm_bridge_connector_destroy(struct >> drm_connector *connector) >> struct drm_bridge_connector *bridge_connector = >> to_drm_bridge_connector(connector); >> >> +if (bridge_connector->bridge_cec) { >> +struct drm_bridge *cec = bridge_connector->bridge_cec; >> + >> +cec->funcs->cec_exit(cec); >> +} >> if (bridge_connector->bridge_hpd) { >> struct drm_bridge *hpd = bridge_connector->bridge_hpd; >> >> @@ -352,6 +364,8 @@ struct drm_connector *drm_bridge_connector_init(struct >> drm_device *drm, >> bridge_connector->bridge_detect = bridge; >> if (bridge->ops & DRM_BRIDGE_OP_MODES) >> bridge_connector->bridge_modes = bridge; >> +if (bridge->ops & DRM_BRIDGE_OP_CEC) >> +bridge_connector->bridge_cec = bridge; >> >> if (!drm_bridge_get_next_bridge(bridge)) >> connector_type = bridge->type; >> @@ -374,6 +388,15 @@ struct drm_connector *drm_bridge_connector_init(struct >> drm_device *drm, >> else if (bridge_connector->bridge_detect) >> connector->polled = DRM_CONNECTOR_POLL_CONNECT >>| DRM_CONNECTOR_POLL_DISCONNECT; >> +if (bridge_connector->bridge_cec) { >> +struct drm_bridge *bridge = bridge_connector->bridge_cec; >> +int ret = bridge->funcs->cec_init(bridge, connector); >> + >> +if (ret) { >> +drm_bridge_connector_destroy(connector); >> +return ERR_PTR(ret); >> +} >> +} >> >> return connector; >> } >> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h >> index 2195daa289d2..4c83c2657e87 100644 >> --- a/include/drm/drm_bridge.h >> +++ b/include/drm/drm_bridge.h >> @@ -629,6 +629,30 @@ struct drm_bridge_funcs { >> * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops. >> */ >> void (*hpd_disable)(struct drm_bridge *bridge); >> + >> +/** >> + * @cec_init: >> + * >> + * Initialize the CEC adapter. >> + * >> + * This callback is optional and shall only be implemented by bridges >> + * that support a CEC adapter. Bridges that implement it shall also >> + * implement the @cec_exit callback and set the DRM_BRIDGE_OP_CEC flag >> + * in their &drm_bridge->ops. >> + */ >> +int (*cec_init)(struct drm_bridge *bridge, struct drm_connector *conn); >> + >> +/** >> + * @cec_exit: >> + * >> + * Terminate the CEC adapter. >> + * >> + * This callback is optional and shall only be implemented by bridges >> + * that support a CEC adapter. Bridges that implement it shall also >> + * implement the @cec_init callback and set the DRM_BRIDGE_OP_CEC flag >> + * in their &drm_bridge->ops. >> + */ >> +void (*cec_exit)(struct drm_bridge *bridge); > > These are very ad-hoc operations. Would it make sense to have something
Re: [PATCH 2/5] drm/omap: hdmi4: switch to the cec bridge ops
On 19/02/2021 13:07, Laurent Pinchart wrote: > Hi Hans, > > Thank you for the patch. > > On Thu, Feb 11, 2021 at 11:37:00AM +0100, Hans Verkuil wrote: >> Implement the new CEC bridge ops. This makes it possible to associate >> a CEC adapter with a drm connector, which helps userspace determine >> with cec device node belongs to which drm connector. >> >> Signed-off-by: Hans Verkuil >> --- >> drivers/gpu/drm/omapdrm/dss/hdmi4.c | 28 + >> drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 8 --- >> drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 7 --- >> 3 files changed, 28 insertions(+), 15 deletions(-) >> >> diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c >> b/drivers/gpu/drm/omapdrm/dss/hdmi4.c >> index 8de41e74e8f8..765379380d4b 100644 >> --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c >> +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c >> @@ -482,6 +482,21 @@ static struct edid *hdmi4_bridge_get_edid(struct >> drm_bridge *bridge, >> return edid; >> } >> >> +static int hdmi4_bridge_cec_init(struct drm_bridge *bridge, >> + struct drm_connector *conn) >> +{ >> +struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); >> + >> +return hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp, conn); >> +} >> + >> +static void hdmi4_bridge_cec_exit(struct drm_bridge *bridge) >> +{ >> +struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); >> + >> +hdmi4_cec_uninit(&hdmi->core); >> +} >> + >> static const struct drm_bridge_funcs hdmi4_bridge_funcs = { >> .attach = hdmi4_bridge_attach, >> .mode_set = hdmi4_bridge_mode_set, >> @@ -492,13 +507,15 @@ static const struct drm_bridge_funcs >> hdmi4_bridge_funcs = { >> .atomic_disable = hdmi4_bridge_disable, >> .hpd_notify = hdmi4_bridge_hpd_notify, >> .get_edid = hdmi4_bridge_get_edid, >> +.cec_init = hdmi4_bridge_cec_init, >> +.cec_exit = hdmi4_bridge_cec_exit, >> }; >> >> static void hdmi4_bridge_init(struct omap_hdmi *hdmi) >> { >> hdmi->bridge.funcs = &hdmi4_bridge_funcs; >> hdmi->bridge.of_node = hdmi->pdev->dev.of_node; >> -hdmi->bridge.ops = DRM_BRIDGE_OP_EDID; >> +hdmi->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_CEC; >> hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; >> >> drm_bridge_add(&hdmi->bridge); >> @@ -647,14 +664,10 @@ static int hdmi4_bind(struct device *dev, struct >> device *master, void *data) >> if (r) >> goto err_runtime_put; >> >> -r = hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp); >> -if (r) >> -goto err_pll_uninit; > > I'm wondering ifwe need to delay the creation of the CEC adapter until > the DRM connector is ready, or if we could only delay its registration ? > Catching errors related to adapter creation early could be nice, the > more error we have to handle at DRM bridge connector creation time, the > more complex the error handling will be for bridge support. I feel that that is overkill, but if you really want this, just let me know. Splitting it up would actually make it more complex for me since I would have to check whether to call cec_unregister_adapter or cec_delete_adapter, depending on whether the CEC registration was successful or not. Regards, Hans > >> - >> r = hdmi_audio_register(hdmi); >> if (r) { >> DSSERR("Registering HDMI audio failed\n"); >> -goto err_cec_uninit; >> +goto err_pll_uninit; >> } >> >> hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs, >> @@ -664,8 +677,6 @@ static int hdmi4_bind(struct device *dev, struct device >> *master, void *data) >> >> return 0; >> >> -err_cec_uninit: >> -hdmi4_cec_uninit(&hdmi->core); >> err_pll_uninit: >> hdmi_pll_uninit(&hdmi->pll); >> err_runtime_put: >> @@ -682,7 +693,6 @@ static void hdmi4_unbind(struct device *dev, struct >> device *master, void *data) >> if (hdmi->audio_pdev) >> platform_device_unregister(hdmi->audio_pdev); >> >> -hdmi4_cec_uninit(&hdmi->core); >> hdmi_pll_uninit(&hdmi->pll); >> } >> >> diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c >> b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c >> index 43592c1cf081..64
Re: [PATCH 4/5] drm/omap: hdmi5: add CEC support
On 19/02/2021 12:09, Tomi Valkeinen wrote: > Hi Hans, > > On 11/02/2021 12:37, Hans Verkuil wrote: >> Add HDMI CEC support for OMAP5. >> >> Many thanks to Tomi for helping out how to enable CEC for omap5. >> >> Signed-off-by: Hans Verkuil >> Thanks-to: Tomi Valkeinen >> --- >> drivers/gpu/drm/omapdrm/dss/Kconfig | 8 + >> drivers/gpu/drm/omapdrm/dss/Makefile | 1 + >> drivers/gpu/drm/omapdrm/dss/hdmi.h | 1 + >> drivers/gpu/drm/omapdrm/dss/hdmi5.c | 63 +-- >> drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c | 201 +++ >> drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h | 42 + >> drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 28 +++- >> drivers/gpu/drm/omapdrm/dss/hdmi5_core.h | 33 +++- >> 8 files changed, 358 insertions(+), 19 deletions(-) >> create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c >> create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h >> >> diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig >> b/drivers/gpu/drm/omapdrm/dss/Kconfig >> index e11b258a2294..67a1ba14703b 100644 >> --- a/drivers/gpu/drm/omapdrm/dss/Kconfig >> +++ b/drivers/gpu/drm/omapdrm/dss/Kconfig >> @@ -83,6 +83,14 @@ config OMAP5_DSS_HDMI >>Definition Multimedia Interface. See https://www.hdmi.org/ for HDMI >>specification. >> >> +config OMAP5_DSS_HDMI_CEC >> +bool "Enable HDMI CEC support for OMAP5" >> +depends on OMAP5_DSS_HDMI >> +select CEC_CORE >> +default y >> +help >> + When selected the HDMI transmitter will support the CEC feature. >> + >> config OMAP2_DSS_SDI >> bool "SDI support" >> default n >> diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile >> b/drivers/gpu/drm/omapdrm/dss/Makefile >> index f967e6948f2e..94fe0fa3b3c2 100644 >> --- a/drivers/gpu/drm/omapdrm/dss/Makefile >> +++ b/drivers/gpu/drm/omapdrm/dss/Makefile >> @@ -17,4 +17,5 @@ omapdss-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += hdmi_common.o >> hdmi_wp.o hdmi_pll.o \ >> omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi4_core.o >> omapdss-$(CONFIG_OMAP4_DSS_HDMI_CEC) += hdmi4_cec.o >> omapdss-$(CONFIG_OMAP5_DSS_HDMI) += hdmi5.o hdmi5_core.o >> +omapdss-$(CONFIG_OMAP5_DSS_HDMI_CEC) += hdmi5_cec.o >> ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG >> diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h >> b/drivers/gpu/drm/omapdrm/dss/hdmi.h >> index c4a4e07f0b99..72d8ae441da6 100644 >> --- a/drivers/gpu/drm/omapdrm/dss/hdmi.h >> +++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h >> @@ -261,6 +261,7 @@ struct hdmi_core_data { >> struct hdmi_wp_data *wp; >> unsigned int core_pwr_cnt; >> struct cec_adapter *adap; >> +struct clk *cec_clk; >> }; >> >> static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, >> diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c >> b/drivers/gpu/drm/omapdrm/dss/hdmi5.c >> index 54e5cb5aa52d..b674d8ba173f 100644 >> --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c >> +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c >> @@ -29,12 +29,14 @@ >> #include >> #include >> #include >> +#include >> >> #include >> #include >> >> #include "omapdss.h" >> #include "hdmi5_core.h" >> +#include "hdmi5_cec.h" >> #include "dss.h" >> >> static int hdmi_runtime_get(struct omap_hdmi *hdmi) >> @@ -104,6 +106,10 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) >> } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { >> hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); >> } > > Empty line here, please. > >> +if (irqstatus & HDMI_IRQ_CORE) { >> +hdmi5_cec_irq(&hdmi->core); >> +hdmi5_core_handle_irqs(&hdmi->core); >> +} > > It's a bit odd to call two functions here. Would it work if > hdmi5_core_handle_irqs() would read and clear HDMI_CORE_IH_CEC_STAT0, > and call hdmi5_cec_irq() if the stat != 0 ? Makes sense, I'll do that. > > And it would be nice if hdmi5_core.c would enable and disable core > interrupt, but maybe that can be left for later if the need ever comes > to handle other interrupts than cec. I prefer to leave it as-is. > >> >> return IRQ_HANDLED; >> } >> @@ -112,9 +118,12 @@ static int hdmi_power_on_core(struct omap_hdmi *hdmi) >> { >> int r; >> >> +if (hdmi->core.core_pwr_cnt++) >> +
[PATCHv2 2/6] drm/omapdrm/dss/hdmi4: switch to the connector bridge ops
Implement the new connector_attach/detach bridge ops. This makes it possible to associate a CEC adapter with a drm connector, which helps userspace determine which cec device node belongs to which drm connector. Signed-off-by: Hans Verkuil --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 27 + drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 9 ++--- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 7 --- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 35b750cebaeb..c387156a5cbb 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -482,6 +482,22 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, return edid; } +static void hdmi4_bridge_connector_attach(struct drm_bridge *bridge, + struct drm_connector *conn) +{ + struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); + + hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp, conn); +} + +static void hdmi4_bridge_connector_detach(struct drm_bridge *bridge, + struct drm_connector *conn) +{ + struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); + + hdmi4_cec_uninit(&hdmi->core); +} + static const struct drm_bridge_funcs hdmi4_bridge_funcs = { .attach = hdmi4_bridge_attach, .mode_set = hdmi4_bridge_mode_set, @@ -492,6 +508,8 @@ static const struct drm_bridge_funcs hdmi4_bridge_funcs = { .atomic_disable = hdmi4_bridge_disable, .hpd_notify = hdmi4_bridge_hpd_notify, .get_edid = hdmi4_bridge_get_edid, + .connector_attach = hdmi4_bridge_connector_attach, + .connector_detach = hdmi4_bridge_connector_detach, }; static void hdmi4_bridge_init(struct omap_hdmi *hdmi) @@ -647,14 +665,10 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data) if (r) goto err_runtime_put; - r = hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp); - if (r) - goto err_pll_uninit; - r = hdmi_audio_register(hdmi); if (r) { DSSERR("Registering HDMI audio failed\n"); - goto err_cec_uninit; + goto err_pll_uninit; } hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs, @@ -664,8 +678,6 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data) return 0; -err_cec_uninit: - hdmi4_cec_uninit(&hdmi->core); err_pll_uninit: hdmi_pll_uninit(&hdmi->pll); err_runtime_put: @@ -682,7 +694,6 @@ static void hdmi4_unbind(struct device *dev, struct device *master, void *data) if (hdmi->audio_pdev) platform_device_unregister(hdmi->audio_pdev); - hdmi4_cec_uninit(&hdmi->core); hdmi_pll_uninit(&hdmi->pll); } diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 43592c1cf081..80ec52c9c846 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -335,10 +335,10 @@ void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) } int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, - struct hdmi_wp_data *wp) + struct hdmi_wp_data *wp, struct drm_connector *conn) { - const u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | -CEC_CAP_PASSTHROUGH | CEC_CAP_RC; + const u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO; + struct cec_connector_info conn_info; int ret; core->adap = cec_allocate_adapter(&hdmi_cec_adap_ops, core, @@ -346,6 +346,8 @@ int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, ret = PTR_ERR_OR_ZERO(core->adap); if (ret < 0) return ret; + cec_fill_conn_info_from_drm(&conn_info, conn); + cec_s_conn_info(core->adap, &conn_info); core->wp = wp; /* Disable clock initially, hdmi_cec_adap_enable() manages it */ @@ -354,6 +356,7 @@ int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, ret = cec_register_adapter(core->adap, &pdev->dev); if (ret < 0) { cec_delete_adapter(core->adap); + core->adap = NULL; return ret; } return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h index 0292337c97cc..b59a54c3040e 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h @@ -29,7 +29,7 @@ struct platform_device; void hdmi4_cec_set_phys_addr(struct hdmi_core_data
[PATCHv2 0/6] drm/omap: hdmi: improve hdmi4 CEC, add CEC for hdmi5
This series improves the drm_bridge support for CEC by introducing two new bridge ops in the first patch, and using those in the second patch. This makes it possible to call cec_s_conn_info() and set CEC_CAP_CONNECTOR_INFO for the CEC adapter, so userspace can associate the CEC adapter with the corresponding DRM connector. The third patch simplifies CEC physical address handling by using the cec_s_phys_addr_from_edid helper function that didn't exist when this code was originally written. The fourth patch adds the cec clock to ti,omap5-dss.txt. The fifth patch the missing cec clock to the dra7 and omap5 device tree, and the last patch adds CEC support to the OMAP5 driver. Tested with a Pandaboard and a Beagle X15 board. Regards, Hans Changes since v1: - as per suggestion from Laurent, changed cec_init/exit to connector_attach/_detach which are just called for all bridges. The DRM_BRIDGE_OP_CEC was dropped. - added patch to add the cec clock to ti,omap5-dss.txt - swapped the order of the last two patches - incorporated Tomi's suggestions for the hdmi5 CEC support. Hans Verkuil (6): drm: drm_bridge: add connector_attach/detach bridge ops drm/omapdrm/dss/hdmi4: switch to the connector bridge ops drm/omapdrm/dss/hdmi4: simplify CEC Phys Addr handling dt-bindings: display: ti: ti,omap5-dss.txt: add cec clock dra7.dtsi/omap5.dtsi: add cec clock drm/omapdrm/dss/hdmi5: add CEC support .../bindings/display/ti/ti,omap5-dss.txt | 4 +- arch/arm/boot/dts/dra7.dtsi | 5 +- arch/arm/boot/dts/omap5.dtsi | 5 +- drivers/gpu/drm/drm_bridge_connector.c| 9 + drivers/gpu/drm/omapdrm/Kconfig | 8 + drivers/gpu/drm/omapdrm/Makefile | 1 + drivers/gpu/drm/omapdrm/dss/hdmi.h| 1 + drivers/gpu/drm/omapdrm/dss/hdmi4.c | 40 ++-- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 13 +- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 12 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 63 +- drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c | 209 ++ drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h | 42 drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 35 ++- drivers/gpu/drm/omapdrm/dss/hdmi5_core.h | 33 ++- include/drm/drm_bridge.h | 27 +++ 16 files changed, 453 insertions(+), 54 deletions(-) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv2 1/6] drm: drm_bridge: add connector_attach/detach bridge ops
Add bridge connector_attach/detach ops. These ops are called when a bridge is attached or detached to a drm_connector. These ops can be used to register and unregister an HDMI CEC adapter for a bridge that supports CEC. Signed-off-by: Hans Verkuil --- drivers/gpu/drm/drm_bridge_connector.c | 9 + include/drm/drm_bridge.h | 27 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index 791379816837..07db71d4f5b3 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -203,6 +203,11 @@ static void drm_bridge_connector_destroy(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) + if (bridge->funcs->connector_detach) + bridge->funcs->connector_detach(bridge, connector); if (bridge_connector->bridge_hpd) { struct drm_bridge *hpd = bridge_connector->bridge_hpd; @@ -375,6 +380,10 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + drm_for_each_bridge_in_chain(encoder, bridge) + if (bridge->funcs->connector_attach) + bridge->funcs->connector_attach(bridge, connector); + return connector; } EXPORT_SYMBOL_GPL(drm_bridge_connector_init); diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 2195daa289d2..3320a6ebd253 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -629,6 +629,33 @@ struct drm_bridge_funcs { * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops. */ void (*hpd_disable)(struct drm_bridge *bridge); + + /** +* @connector_attach: +* +* This callback is invoked whenever our bridge is being attached to a +* &drm_connector. This is where an HDMI CEC adapter can be registered. +* Note that this callback expects that this op always succeeds. Since +* HDMI CEC support is an optional feature, any failure to register a +* CEC adapter must be ignored since video output will still work +* without CEC. +* +* The @connector_attach callback is optional. +*/ + void (*connector_attach)(struct drm_bridge *bridge, +struct drm_connector *conn); + + /** +* @connector_detach: +* +* This callback is invoked whenever our bridge is being detached from a +* &drm_connector. This is where an HDMI CEC adapter can be +* unregistered. +* +* The @connector_detach callback is optional. +*/ + void (*connector_detach)(struct drm_bridge *bridge, +struct drm_connector *conn); }; /** -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv2 4/6] dt-bindings: display: ti: ti, omap5-dss.txt: add cec clock
The cec clock is required as well in order to support HDMI CEC, document this. Signed-off-by: Hans Verkuil --- Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt b/Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt index 20861218649f..c321c67472f0 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt +++ b/Documentation/devicetree/bindings/display/ti/ti,omap5-dss.txt @@ -89,8 +89,8 @@ Required properties: - interrupts: the HDMI interrupt line - ti,hwmods: "dss_hdmi" - vdda-supply: vdda power supply -- clocks: handles to fclk and pll clock -- clock-names: "fck", "sys_clk" +- clocks: handles to fclk, pll and cec clock +- clock-names: "fck", "sys_clk", "cec" Optional nodes: - Video port for HDMI output -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv2 3/6] drm/omapdrm/dss/hdmi4: simplify CEC Phys Addr handling
Switch to using cec_s_phys_addr_from_edid() instead of a two-step process of calling cec_get_edid_phys_addr() followed by cec_s_phys_addr(). Signed-off-by: Hans Verkuil Reviewed-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 13 ++--- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 4 ++-- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 5 +++-- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index c387156a5cbb..73f6ed3b75ee 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -432,7 +432,7 @@ static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge, struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); if (status == connector_status_disconnected) - hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID); + hdmi4_cec_set_phys_addr(&hdmi->core, NULL); } static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, @@ -440,7 +440,6 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, { struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); struct edid *edid = NULL; - unsigned int cec_addr; bool need_enable; int r; @@ -466,15 +465,7 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, hdmi_runtime_put(hdmi); mutex_unlock(&hdmi->lock); - if (edid && edid->extensions) { - unsigned int len = (edid->extensions + 1) * EDID_LENGTH; - - cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL); - } else { - cec_addr = CEC_PHYS_ADDR_INVALID; - } - - hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr); + hdmi4_cec_set_phys_addr(&hdmi->core, edid); if (need_enable) hdmi4_core_disable(&hdmi->core); diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 80ec52c9c846..cf406d86c845 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -329,9 +329,9 @@ static const struct cec_adap_ops hdmi_cec_adap_ops = { .adap_transmit = hdmi_cec_adap_transmit, }; -void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) +void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, struct edid *edid) { - cec_s_phys_addr(core->adap, pa, false); + cec_s_phys_addr_from_edid(core->adap, edid); } int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h index b59a54c3040e..16bf259643b7 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h @@ -26,13 +26,14 @@ struct platform_device; /* HDMI CEC funcs */ #ifdef CONFIG_OMAP4_DSS_HDMI_CEC -void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa); +void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, struct edid *edid); void hdmi4_cec_irq(struct hdmi_core_data *core); int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, struct hdmi_wp_data *wp, struct drm_connector *conn); void hdmi4_cec_uninit(struct hdmi_core_data *core); #else -static inline void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) +static inline void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, + struct edid *edid) { } -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv2 5/6] dra7.dtsi/omap5.dtsi: add cec clock
Add cec clock to the dra7 and omap5 device trees. Signed-off-by: Hans Verkuil Acked-by: Tony Lindgren --- arch/arm/boot/dts/dra7.dtsi | 5 +++-- arch/arm/boot/dts/omap5.dtsi | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index ce1194744f84..efe579ddb324 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -879,8 +879,9 @@ hdmi: encoder@0 { interrupts = ; status = "disabled"; clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>, -<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; +<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>, +<&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "sys_clk", "cec"; dmas = <&sdma_xbar 76>; dma-names = "audio_tx"; }; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index e025b7c9a357..6726e1f1b07c 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -586,8 +586,9 @@ hdmi: encoder@0 { interrupts = ; status = "disabled"; clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 9>, -<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; - clock-names = "fck", "sys_clk"; +<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>, +<&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 11>; + clock-names = "fck", "sys_clk", "cec"; dmas = <&sdma 76>; dma-names = "audio_tx"; }; -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv2 6/6] drm/omapdrm/dss/hdmi5: add CEC support
Add HDMI CEC support for OMAP5. Signed-off-by: Hans Verkuil --- drivers/gpu/drm/omapdrm/Kconfig | 8 + drivers/gpu/drm/omapdrm/Makefile | 1 + drivers/gpu/drm/omapdrm/dss/hdmi.h | 1 + drivers/gpu/drm/omapdrm/dss/hdmi5.c | 63 +-- drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c | 209 +++ drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h | 42 + drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 35 +++- drivers/gpu/drm/omapdrm/dss/hdmi5_core.h | 33 +++- 8 files changed, 373 insertions(+), 19 deletions(-) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig index e7281da5bc6a..08866ac7d869 100644 --- a/drivers/gpu/drm/omapdrm/Kconfig +++ b/drivers/gpu/drm/omapdrm/Kconfig @@ -80,6 +80,14 @@ config OMAP5_DSS_HDMI Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI specification. +config OMAP5_DSS_HDMI_CEC + bool "Enable HDMI CEC support for OMAP5" + depends on OMAP5_DSS_HDMI + select CEC_CORE + default y + help + When selected the HDMI transmitter will support the CEC feature. + config OMAP2_DSS_SDI bool "SDI support" default n diff --git a/drivers/gpu/drm/omapdrm/Makefile b/drivers/gpu/drm/omapdrm/Makefile index 21e8277ff88f..0732bd2dae1e 100644 --- a/drivers/gpu/drm/omapdrm/Makefile +++ b/drivers/gpu/drm/omapdrm/Makefile @@ -29,6 +29,7 @@ omapdrm-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += dss/hdmi_common.o dss/hdmi_wp.o \ omapdrm-$(CONFIG_OMAP4_DSS_HDMI) += dss/hdmi4.o dss/hdmi4_core.o omapdrm-$(CONFIG_OMAP4_DSS_HDMI_CEC) += dss/hdmi4_cec.o omapdrm-$(CONFIG_OMAP5_DSS_HDMI) += dss/hdmi5.o dss/hdmi5_core.o +omapdrm-$(CONFIG_OMAP5_DSS_HDMI_CEC) += dss/hdmi5_cec.o ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG obj-$(CONFIG_DRM_OMAP) += omapdrm.o diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h index c4a4e07f0b99..72d8ae441da6 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h @@ -261,6 +261,7 @@ struct hdmi_core_data { struct hdmi_wp_data *wp; unsigned int core_pwr_cnt; struct cec_adapter *adap; + struct clk *cec_clk; }; static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 65085d886da5..561d57f2dd04 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -29,12 +29,14 @@ #include #include #include +#include #include #include #include "omapdss.h" #include "hdmi5_core.h" +#include "hdmi5_cec.h" #include "dss.h" static int hdmi_runtime_get(struct omap_hdmi *hdmi) @@ -105,6 +107,9 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); } + if (irqstatus & HDMI_IRQ_CORE) + hdmi5_core_handle_irqs(&hdmi->core); + return IRQ_HANDLED; } @@ -112,9 +117,12 @@ static int hdmi_power_on_core(struct omap_hdmi *hdmi) { int r; + if (hdmi->core.core_pwr_cnt++) + return 0; + r = regulator_enable(hdmi->vdda_reg); if (r) - return r; + goto err_reg_enable; r = hdmi_runtime_get(hdmi); if (r) @@ -129,12 +137,17 @@ static int hdmi_power_on_core(struct omap_hdmi *hdmi) err_runtime_get: regulator_disable(hdmi->vdda_reg); +err_reg_enable: + hdmi->core.core_pwr_cnt--; return r; } static void hdmi_power_off_core(struct omap_hdmi *hdmi) { + if (--hdmi->core.core_pwr_cnt) + return; + hdmi->core_enabled = false; hdmi_runtime_put(hdmi); @@ -168,9 +181,9 @@ static int hdmi_power_on_full(struct omap_hdmi *hdmi) pc, &hdmi_cinfo); /* disable and clear irqs */ - hdmi_wp_clear_irqenable(&hdmi->wp, 0x); + hdmi_wp_clear_irqenable(&hdmi->wp, ~HDMI_IRQ_CORE); hdmi_wp_set_irqstatus(&hdmi->wp, - hdmi_wp_get_irqstatus(&hdmi->wp)); + hdmi_wp_get_irqstatus(&hdmi->wp) & ~HDMI_IRQ_CORE); r = dss_pll_enable(&hdmi->pll.pll); if (r) { @@ -225,7 +238,7 @@ static int hdmi_power_on_full(struct omap_hdmi *hdmi) static void hdmi_power_off_full(struct omap_hdmi *hdmi) { - hdmi_wp_clear_irqenable(&hdmi->wp, 0x); + hdmi_wp_clear_irqenable(&hdmi->wp, ~HDMI_IRQ_CORE); hdmi_wp_video_stop(&hdmi->wp); @@ -273,11 +286,11 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd) REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_i
Re: [PATCHv2 6/6] drm/omapdrm/dss/hdmi5: add CEC support
On 03/03/2021 08:47, Tomi Valkeinen wrote: > On 02/03/2021 18:24, Hans Verkuil wrote: >> Add HDMI CEC support for OMAP5. >> >> Signed-off-by: Hans Verkuil >> --- >> drivers/gpu/drm/omapdrm/Kconfig | 8 + >> drivers/gpu/drm/omapdrm/Makefile | 1 + >> drivers/gpu/drm/omapdrm/dss/hdmi.h | 1 + >> drivers/gpu/drm/omapdrm/dss/hdmi5.c | 63 +-- >> drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c | 209 +++ >> drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h | 42 + >> drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 35 +++- >> drivers/gpu/drm/omapdrm/dss/hdmi5_core.h | 33 +++- >> 8 files changed, 373 insertions(+), 19 deletions(-) >> create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c >> create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h > > > >> diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.h >> b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.h >> index 070cbf5fb57d..a83b634f6011 100644 >> --- a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.h >> +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.h >> @@ -30,8 +30,18 @@ >> #define HDMI_CORE_IH_PHY_STAT0 0x00410 >> #define HDMI_CORE_IH_I2CM_STAT00x00414 >> #define HDMI_CORE_IH_CEC_STAT0 0x00418 >> +#define CEC_STAT_DONE BIT(0) >> +#define CEC_STAT_EOMBIT(1) >> +#define CEC_STAT_NACK BIT(2) >> +#define CEC_STAT_ARBLOSTBIT(3) >> +#define CEC_STAT_ERROR_INIT BIT(4) >> +#define CEC_STAT_ERROR_FOLL BIT(5) >> +#define CEC_STAT_WAKEUP BIT(6) >> + >> #define HDMI_CORE_IH_VP_STAT0 0x0041C >> #define HDMI_CORE_IH_I2CMPHY_STAT0 0x00420 >> +#define HDMI_CORE_IH_MUTE_I2CM_STAT00x00614 > > The line above has indentation in spaces, but everything else uses tabs. Well spotted! I've fixed that in my tree. > > Other than that: > > Reviewed-by: Tomi Valkeinen Thanks! Hans > > Tomi > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 0/7] sunxi: Remove the calls to dma_direct_set_offset
On 06/11/2020 16:14, Maxime Ripard wrote: > Hi, > > Here's an attempt to removing the dma_direct_set_offset calls we have in > numerous drivers and move all those quirks into a global notifier as suggested > by Robin. For patches 4-7: Acked-by: Hans Verkuil It's fine by me if this series is merged via the drm subsystem. Regards, Hans > > Let me know what you think, > Maxime > > Maxime Ripard (7): > drm/sun4i: backend: Fix probe failure with multiple backends > soc: sunxi: Deal with the MBUS DMA offsets in a central place > drm/sun4i: backend: Remove the MBUS quirks > media: sun4i: Remove the MBUS quirks > media: sun6i: Remove the MBUS quirks > media: cedrus: Remove the MBUS quirks > media: sun8i-di: Remove the call to of_dma_configure > > drivers/gpu/drm/sun4i/sun4i_backend.c | 13 -- > .../platform/sunxi/sun4i-csi/sun4i_csi.c | 27 > .../platform/sunxi/sun6i-csi/sun6i_csi.c | 17 --- > .../media/platform/sunxi/sun8i-di/sun8i-di.c | 4 - > drivers/soc/sunxi/Kconfig | 8 ++ > drivers/soc/sunxi/Makefile| 1 + > drivers/soc/sunxi/sunxi_mbus.c| 132 ++ > drivers/staging/media/sunxi/cedrus/cedrus.c | 1 - > drivers/staging/media/sunxi/cedrus/cedrus.h | 3 - > .../staging/media/sunxi/cedrus/cedrus_hw.c| 18 --- > 10 files changed, 141 insertions(+), 83 deletions(-) > create mode 100644 drivers/soc/sunxi/sunxi_mbus.c > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 09/17] media/videbuf1|2: Mark follow_pfn usage as unsafe
On 19/11/2020 15:41, Daniel Vetter wrote: > The media model assumes that buffers are all preallocated, so that > when a media pipeline is running we never miss a deadline because the > buffers aren't allocated or available. > > This means we cannot fix the v4l follow_pfn usage through > mmu_notifier, without breaking how this all works. The only real fix > is to deprecate userptr support for VM_IO | VM_PFNMAP mappings and > tell everyone to cut over to dma-buf memory sharing for zerocopy. > > userptr for normal memory will keep working as-is, this only affects > the zerocopy userptr usage enabled in 50ac952d2263 ("[media] > videobuf2-dma-sg: Support io userptr operations on io memory"). > > Acked-by: Tomasz Figa Acked-by: Hans Verkuil Thanks! Hans > Signed-off-by: Daniel Vetter > Cc: Jason Gunthorpe > Cc: Kees Cook > Cc: Dan Williams > Cc: Andrew Morton > Cc: John Hubbard > Cc: Jérôme Glisse > Cc: Jan Kara > Cc: Dan Williams > Cc: linux...@kvack.org > Cc: linux-arm-ker...@lists.infradead.org > Cc: linux-samsung-...@vger.kernel.org > Cc: linux-me...@vger.kernel.org > Cc: Pawel Osciak > Cc: Marek Szyprowski > Cc: Kyungmin Park > Cc: Tomasz Figa > Cc: Laurent Dufour > Cc: Vlastimil Babka > Cc: Daniel Jordan > Cc: Michel Lespinasse > Signed-off-by: Daniel Vetter > -- > v3: > - Reference the commit that enabled the zerocopy userptr use case to > make it abundandtly clear that this patch only affects that, and not > normal memory userptr. The old commit message already explained that > normal memory userptr is unaffected, but I guess that was not clear > enough. > --- > drivers/media/common/videobuf2/frame_vector.c | 2 +- > drivers/media/v4l2-core/videobuf-dma-contig.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/common/videobuf2/frame_vector.c > b/drivers/media/common/videobuf2/frame_vector.c > index a0e65481a201..1a82ec13ea00 100644 > --- a/drivers/media/common/videobuf2/frame_vector.c > +++ b/drivers/media/common/videobuf2/frame_vector.c > @@ -70,7 +70,7 @@ int get_vaddr_frames(unsigned long start, unsigned int > nr_frames, > break; > > while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) { > - err = follow_pfn(vma, start, &nums[ret]); > + err = unsafe_follow_pfn(vma, start, &nums[ret]); > if (err) { > if (ret == 0) > ret = err; > diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c > b/drivers/media/v4l2-core/videobuf-dma-contig.c > index 52312ce2ba05..821c4a76ab96 100644 > --- a/drivers/media/v4l2-core/videobuf-dma-contig.c > +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c > @@ -183,7 +183,7 @@ static int videobuf_dma_contig_user_get(struct > videobuf_dma_contig_memory *mem, > user_address = untagged_baddr; > > while (pages_done < (mem->size >> PAGE_SHIFT)) { > - ret = follow_pfn(vma, user_address, &this_pfn); > + ret = unsafe_follow_pfn(vma, user_address, &this_pfn); > if (ret) > break; > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 06/17] media: videobuf2: Move frame_vector into media subsystem
On 19/11/2020 15:41, Daniel Vetter wrote: > It's the only user. This also garbage collects the CONFIG_FRAME_VECTOR > symbol from all over the tree (well just one place, somehow omap media > driver still had this in its Kconfig, despite not using it). > > Reviewed-by: John Hubbard > Acked-by: Mauro Carvalho Chehab > Acked-by: Tomasz Figa Acked-by: Hans Verkuil Thanks! Hans > Signed-off-by: Daniel Vetter > Cc: Jason Gunthorpe > Cc: Pawel Osciak > Cc: Marek Szyprowski > Cc: Kyungmin Park > Cc: Tomasz Figa > Cc: Mauro Carvalho Chehab > Cc: Andrew Morton > Cc: John Hubbard > Cc: Jérôme Glisse > Cc: Jan Kara > Cc: Dan Williams > Cc: linux...@kvack.org > Cc: linux-arm-ker...@lists.infradead.org > Cc: linux-samsung-...@vger.kernel.org > Cc: linux-me...@vger.kernel.org > Cc: Daniel Vetter > Signed-off-by: Daniel Vetter > -- > v3: > - Create a new frame_vector.h header for this (Mauro) > v5: > - Rebase over changes in frame-vector.c from Tomasz review. > --- > drivers/media/common/videobuf2/Kconfig| 1 - > drivers/media/common/videobuf2/Makefile | 1 + > .../media/common/videobuf2}/frame_vector.c| 2 + > drivers/media/platform/omap/Kconfig | 1 - > include/linux/mm.h| 42 - > include/media/frame_vector.h | 47 +++ > include/media/videobuf2-core.h| 1 + > mm/Kconfig| 3 -- > mm/Makefile | 1 - > 9 files changed, 51 insertions(+), 48 deletions(-) > rename {mm => drivers/media/common/videobuf2}/frame_vector.c (99%) > create mode 100644 include/media/frame_vector.h > > diff --git a/drivers/media/common/videobuf2/Kconfig > b/drivers/media/common/videobuf2/Kconfig > index edbc99ebba87..d2223a12c95f 100644 > --- a/drivers/media/common/videobuf2/Kconfig > +++ b/drivers/media/common/videobuf2/Kconfig > @@ -9,7 +9,6 @@ config VIDEOBUF2_V4L2 > > config VIDEOBUF2_MEMOPS > tristate > - select FRAME_VECTOR > > config VIDEOBUF2_DMA_CONTIG > tristate > diff --git a/drivers/media/common/videobuf2/Makefile > b/drivers/media/common/videobuf2/Makefile > index 77bebe8b202f..54306f8d096c 100644 > --- a/drivers/media/common/videobuf2/Makefile > +++ b/drivers/media/common/videobuf2/Makefile > @@ -1,5 +1,6 @@ > # SPDX-License-Identifier: GPL-2.0 > videobuf2-common-objs := videobuf2-core.o > +videobuf2-common-objs += frame_vector.o > > ifeq ($(CONFIG_TRACEPOINTS),y) >videobuf2-common-objs += vb2-trace.o > diff --git a/mm/frame_vector.c b/drivers/media/common/videobuf2/frame_vector.c > similarity index 99% > rename from mm/frame_vector.c > rename to drivers/media/common/videobuf2/frame_vector.c > index f8c34b895c76..a0e65481a201 100644 > --- a/mm/frame_vector.c > +++ b/drivers/media/common/videobuf2/frame_vector.c > @@ -8,6 +8,8 @@ > #include > #include > > +#include > + > /** > * get_vaddr_frames() - map virtual addresses to pfns > * @start: starting user address > diff --git a/drivers/media/platform/omap/Kconfig > b/drivers/media/platform/omap/Kconfig > index f73b5893220d..de16de46c0f4 100644 > --- a/drivers/media/platform/omap/Kconfig > +++ b/drivers/media/platform/omap/Kconfig > @@ -12,6 +12,5 @@ config VIDEO_OMAP2_VOUT > depends on VIDEO_V4L2 > select VIDEOBUF2_DMA_CONTIG > select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 > - select FRAME_VECTOR > help > V4L2 Display driver support for OMAP2/3 based boards. > diff --git a/include/linux/mm.h b/include/linux/mm.h > index efb8c39bc933..b1a4a140863d 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -1751,48 +1751,6 @@ int account_locked_vm(struct mm_struct *mm, unsigned > long pages, bool inc); > int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, > struct task_struct *task, bool bypass_rlim); > > -/* Container for pinned pfns / pages */ > -struct frame_vector { > - unsigned int nr_allocated; /* Number of frames we have space for */ > - unsigned int nr_frames; /* Number of frames stored in ptrs array */ > - bool got_ref; /* Did we pin pages by getting page ref? */ > - bool is_pfns; /* Does array contain pages or pfns? */ > - void *ptrs[]; /* Array of pinned pfns / pages. Use > - * pfns_vector_pages() or pfns_vector_pfns() > - * for access */ > -}; > - > -struct frame_vector *frame_vector_create(unsigned int nr_frames); > -void frame_vector_destroy(
Re: [PATCH v6 09/17] media/videbuf1|2: Mark follow_pfn usage as unsafe
On 20/11/2020 09:06, Hans Verkuil wrote: > On 19/11/2020 15:41, Daniel Vetter wrote: >> The media model assumes that buffers are all preallocated, so that >> when a media pipeline is running we never miss a deadline because the >> buffers aren't allocated or available. >> >> This means we cannot fix the v4l follow_pfn usage through >> mmu_notifier, without breaking how this all works. The only real fix >> is to deprecate userptr support for VM_IO | VM_PFNMAP mappings and >> tell everyone to cut over to dma-buf memory sharing for zerocopy. >> >> userptr for normal memory will keep working as-is, this only affects >> the zerocopy userptr usage enabled in 50ac952d2263 ("[media] >> videobuf2-dma-sg: Support io userptr operations on io memory"). >> >> Acked-by: Tomasz Figa > > Acked-by: Hans Verkuil Actually, cancel this Acked-by. So let me see if I understand this right: VM_IO | VM_PFNMAP mappings can move around. There is a mmu_notifier that can be used to be notified when that happens, but that can't be used with media buffers since those buffers must always be available and in the same place. So follow_pfn is replaced by unsafe_follow_pfn to signal that what is attempted is unsafe and unreliable. If CONFIG_STRICT_FOLLOW_PFN is set, then unsafe_follow_pfn will fail, if it is unset, then it writes a warning to the kernel log but just continues while still unsafe. I am very much inclined to just drop VM_IO | VM_PFNMAP support in the media subsystem. For vb2 there is a working alternative in the form of dmabuf, and frankly for vb1 I don't care. If someone really needs this for a vb1 driver, then they can do the work to convert that driver to vb2. I've added Mauro to the CC list and I'll ping a few more people to see what they think, but in my opinion support for USERPTR + VM_IO | VM_PFNMAP should just be killed off. If others would like to keep it, then frame_vector.c needs a comment before the 'while' explaining why the unsafe_follow_pfn is there and that using dmabuf is the proper alternative to use. That will make it easier for developers to figure out why they see a kernel warning and what to do to fix it, rather than having to dig through the git history for the reason. Regards, Hans > > Thanks! > > Hans > >> Signed-off-by: Daniel Vetter >> Cc: Jason Gunthorpe >> Cc: Kees Cook >> Cc: Dan Williams >> Cc: Andrew Morton >> Cc: John Hubbard >> Cc: Jérôme Glisse >> Cc: Jan Kara >> Cc: Dan Williams >> Cc: linux...@kvack.org >> Cc: linux-arm-ker...@lists.infradead.org >> Cc: linux-samsung-...@vger.kernel.org >> Cc: linux-me...@vger.kernel.org >> Cc: Pawel Osciak >> Cc: Marek Szyprowski >> Cc: Kyungmin Park >> Cc: Tomasz Figa >> Cc: Laurent Dufour >> Cc: Vlastimil Babka >> Cc: Daniel Jordan >> Cc: Michel Lespinasse >> Signed-off-by: Daniel Vetter >> -- >> v3: >> - Reference the commit that enabled the zerocopy userptr use case to >> make it abundandtly clear that this patch only affects that, and not >> normal memory userptr. The old commit message already explained that >> normal memory userptr is unaffected, but I guess that was not clear >> enough. >> --- >> drivers/media/common/videobuf2/frame_vector.c | 2 +- >> drivers/media/v4l2-core/videobuf-dma-contig.c | 2 +- >> 2 files changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/media/common/videobuf2/frame_vector.c >> b/drivers/media/common/videobuf2/frame_vector.c >> index a0e65481a201..1a82ec13ea00 100644 >> --- a/drivers/media/common/videobuf2/frame_vector.c >> +++ b/drivers/media/common/videobuf2/frame_vector.c >> @@ -70,7 +70,7 @@ int get_vaddr_frames(unsigned long start, unsigned int >> nr_frames, >> break; >> >> while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) { >> -err = follow_pfn(vma, start, &nums[ret]); >> +err = unsafe_follow_pfn(vma, start, &nums[ret]); >> if (err) { >> if (ret == 0) >> ret = err; >> diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c >> b/drivers/media/v4l2-core/videobuf-dma-contig.c >> index 52312ce2ba05..821c4a76ab96 100644 >> --- a/drivers/media/v4l2-core/videobuf-dma-contig.c >> +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c >> @@ -183,7 +183,7 @@ static int videobuf_dma_contig_user_get(struct >> videobuf_dma_contig_memory *mem, >> user_address = untagged_baddr; >> >> while (pages_done < (mem->size >> PAGE_SHIFT)) { >> -ret = follow_pfn(vma, user_address, &this_pfn); >> +ret = unsafe_follow_pfn(vma, user_address, &this_pfn); >> if (ret) >> break; >> >> > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 09/17] media/videbuf1|2: Mark follow_pfn usage as unsafe
On 20/11/2020 10:18, Daniel Vetter wrote: > On Fri, Nov 20, 2020 at 9:28 AM Hans Verkuil wrote: >> >> On 20/11/2020 09:06, Hans Verkuil wrote: >>> On 19/11/2020 15:41, Daniel Vetter wrote: >>>> The media model assumes that buffers are all preallocated, so that >>>> when a media pipeline is running we never miss a deadline because the >>>> buffers aren't allocated or available. >>>> >>>> This means we cannot fix the v4l follow_pfn usage through >>>> mmu_notifier, without breaking how this all works. The only real fix >>>> is to deprecate userptr support for VM_IO | VM_PFNMAP mappings and >>>> tell everyone to cut over to dma-buf memory sharing for zerocopy. >>>> >>>> userptr for normal memory will keep working as-is, this only affects >>>> the zerocopy userptr usage enabled in 50ac952d2263 ("[media] >>>> videobuf2-dma-sg: Support io userptr operations on io memory"). >>>> >>>> Acked-by: Tomasz Figa >>> >>> Acked-by: Hans Verkuil >> >> Actually, cancel this Acked-by. >> >> So let me see if I understand this right: VM_IO | VM_PFNMAP mappings can >> move around. There is a mmu_notifier that can be used to be notified when >> that happens, but that can't be used with media buffers since those buffers >> must always be available and in the same place. >> >> So follow_pfn is replaced by unsafe_follow_pfn to signal that what is >> attempted >> is unsafe and unreliable. >> >> If CONFIG_STRICT_FOLLOW_PFN is set, then unsafe_follow_pfn will fail, if it >> is unset, then it writes a warning to the kernel log but just continues while >> still unsafe. >> >> I am very much inclined to just drop VM_IO | VM_PFNMAP support in the media >> subsystem. For vb2 there is a working alternative in the form of dmabuf, and >> frankly for vb1 I don't care. If someone really needs this for a vb1 driver, >> then they can do the work to convert that driver to vb2. >> >> I've added Mauro to the CC list and I'll ping a few more people to see what >> they think, but in my opinion support for USERPTR + VM_IO | VM_PFNMAP >> should just be killed off. >> >> If others would like to keep it, then frame_vector.c needs a comment before >> the 'while' explaining why the unsafe_follow_pfn is there and that using >> dmabuf is the proper alternative to use. That will make it easier for >> developers to figure out why they see a kernel warning and what to do to >> fix it, rather than having to dig through the git history for the reason. > > I'm happy to add a comment, but otherwise if you all want to ditch > this, can we do this as a follow up on top? There's quite a bit of > code that can be deleted and I'd like to not hold up this patch set > here on that - it's already a fairly sprawling pain touching about 7 > different subsystems (ok only 6-ish now since the s390 patch landed). > For the comment, is the explanation next to unsafe_follow_pfn not good > enough? No, because that doesn't mention that you should use dma-buf as a replacement. That's really the critical piece of information I'd like to see. That doesn't belong in unsafe_follow_pfn, it needs to be in frame_vector.c since it's vb2 specific. > > So ... can I get you to un-cancel your ack? Hmm, I really would like to see support for this to be dropped completely. How about this: just replace follow_pfn() by -EINVAL instead of unsafe_follow_pfn(). Add a TODO comment that this code now can be cleaned up a lot. Such a clean up patch can be added on top later, and actually that is something that I can do once this series has landed. Regardless, frame_vector.c should mention dma-buf as a replacement in a comment since I don't want users who hit this issue to have to dig through git logs to find that dma-buf is the right approach. BTW, nitpick: the subject line of this patch says 'videbuf' instead of 'videobuf'. Regards, Hans > > Thanks, Daniel > >> >> Regards, >> >> Hans >> >>> >>> Thanks! >>> >>> Hans >>> >>>> Signed-off-by: Daniel Vetter >>>> Cc: Jason Gunthorpe >>>> Cc: Kees Cook >>>> Cc: Dan Williams >>>> Cc: Andrew Morton >>>> Cc: John Hubbard >>>> Cc: Jérôme Glisse >>>> Cc: Jan Kara >>>> Cc: Dan Williams >>>> Cc: linux...@kvack.org >>>> Cc: linux-arm-ker...@lists.infradead.org >>>> Cc
Re: [PATCH v6 09/17] media/videbuf1|2: Mark follow_pfn usage as unsafe
On 20/11/2020 11:51, Daniel Vetter wrote: > On Fri, Nov 20, 2020 at 11:39 AM Hans Verkuil wrote: >> >> On 20/11/2020 10:18, Daniel Vetter wrote: >>> On Fri, Nov 20, 2020 at 9:28 AM Hans Verkuil wrote: >>>> >>>> On 20/11/2020 09:06, Hans Verkuil wrote: >>>>> On 19/11/2020 15:41, Daniel Vetter wrote: >>>>>> The media model assumes that buffers are all preallocated, so that >>>>>> when a media pipeline is running we never miss a deadline because the >>>>>> buffers aren't allocated or available. >>>>>> >>>>>> This means we cannot fix the v4l follow_pfn usage through >>>>>> mmu_notifier, without breaking how this all works. The only real fix >>>>>> is to deprecate userptr support for VM_IO | VM_PFNMAP mappings and >>>>>> tell everyone to cut over to dma-buf memory sharing for zerocopy. >>>>>> >>>>>> userptr for normal memory will keep working as-is, this only affects >>>>>> the zerocopy userptr usage enabled in 50ac952d2263 ("[media] >>>>>> videobuf2-dma-sg: Support io userptr operations on io memory"). >>>>>> >>>>>> Acked-by: Tomasz Figa >>>>> >>>>> Acked-by: Hans Verkuil >>>> >>>> Actually, cancel this Acked-by. >>>> >>>> So let me see if I understand this right: VM_IO | VM_PFNMAP mappings can >>>> move around. There is a mmu_notifier that can be used to be notified when >>>> that happens, but that can't be used with media buffers since those buffers >>>> must always be available and in the same place. >>>> >>>> So follow_pfn is replaced by unsafe_follow_pfn to signal that what is >>>> attempted >>>> is unsafe and unreliable. >>>> >>>> If CONFIG_STRICT_FOLLOW_PFN is set, then unsafe_follow_pfn will fail, if it >>>> is unset, then it writes a warning to the kernel log but just continues >>>> while >>>> still unsafe. >>>> >>>> I am very much inclined to just drop VM_IO | VM_PFNMAP support in the media >>>> subsystem. For vb2 there is a working alternative in the form of dmabuf, >>>> and >>>> frankly for vb1 I don't care. If someone really needs this for a vb1 >>>> driver, >>>> then they can do the work to convert that driver to vb2. >>>> >>>> I've added Mauro to the CC list and I'll ping a few more people to see what >>>> they think, but in my opinion support for USERPTR + VM_IO | VM_PFNMAP >>>> should just be killed off. >>>> >>>> If others would like to keep it, then frame_vector.c needs a comment before >>>> the 'while' explaining why the unsafe_follow_pfn is there and that using >>>> dmabuf is the proper alternative to use. That will make it easier for >>>> developers to figure out why they see a kernel warning and what to do to >>>> fix it, rather than having to dig through the git history for the reason. >>> >>> I'm happy to add a comment, but otherwise if you all want to ditch >>> this, can we do this as a follow up on top? There's quite a bit of >>> code that can be deleted and I'd like to not hold up this patch set >>> here on that - it's already a fairly sprawling pain touching about 7 >>> different subsystems (ok only 6-ish now since the s390 patch landed). >>> For the comment, is the explanation next to unsafe_follow_pfn not good >>> enough? >> >> No, because that doesn't mention that you should use dma-buf as a >> replacement. >> That's really the critical piece of information I'd like to see. That doesn't >> belong in unsafe_follow_pfn, it needs to be in frame_vector.c since it's >> vb2 specific. > > Ah makes sense, I'll add that. > >>> >>> So ... can I get you to un-cancel your ack? >> >> Hmm, I really would like to see support for this to be dropped completely. >> >> How about this: just replace follow_pfn() by -EINVAL instead of >> unsafe_follow_pfn(). >> >> Add a TODO comment that this code now can be cleaned up a lot. Such a clean >> up patch >> can be added on top later, and actually that is something that I can do once >> this >> series has landed. >> >> Regardless, frame_vector.c should mention dma-buf as a replacement in a >> comment &g
Re: [PATCH 5/5] spi: make remove callback a void function
| 4 +--- > drivers/iio/dac/ad5686-spi.c | 4 +--- > drivers/iio/dac/ad5761.c | 4 +--- > drivers/iio/dac/ad5764.c | 4 +--- > drivers/iio/dac/ad5791.c | 4 +--- > drivers/iio/dac/ad8801.c | 4 +--- > drivers/iio/dac/ltc1660.c | 4 +--- > drivers/iio/dac/ltc2632.c | 4 +--- > drivers/iio/dac/mcp4922.c | 4 +--- > drivers/iio/dac/ti-dac082s085.c | 4 +--- > drivers/iio/dac/ti-dac7311.c | 3 +-- > drivers/iio/frequency/adf4350.c | 4 +--- > drivers/iio/gyro/bmg160_spi.c | 4 +--- > drivers/iio/gyro/fxas21002c_spi.c | 4 +--- > drivers/iio/health/afe4403.c | 4 +--- > drivers/iio/magnetometer/bmc150_magn_spi.c| 4 +--- > drivers/iio/magnetometer/hmc5843_spi.c| 4 +--- > drivers/iio/potentiometer/max5487.c | 4 +--- > drivers/iio/pressure/ms5611_spi.c | 4 +--- > drivers/iio/pressure/zpa2326_spi.c| 4 +--- > drivers/input/keyboard/applespi.c | 4 +--- > drivers/input/misc/adxl34x-spi.c | 4 +--- > drivers/input/touchscreen/ads7846.c | 4 +--- > drivers/input/touchscreen/cyttsp4_spi.c | 4 +--- > drivers/input/touchscreen/tsc2005.c | 4 +--- > drivers/leds/leds-cr0014114.c | 4 +--- > drivers/leds/leds-dac124s085.c| 4 +--- > drivers/leds/leds-el15203000.c| 4 +--- > drivers/leds/leds-spi-byte.c | 4 +--- > drivers/media/spi/cxd2880-spi.c | 4 +--- > drivers/media/spi/gs1662.c| 4 +--- > drivers/media/tuners/msi001.c | 3 +-- A bit late, but for drivers/media: Acked-by: Hans Verkuil Thanks! Hans
Re: [PATCH v11 24/34] media: staging: tegra-vde: Support generic power domain
On 12/09/2021 22:08, Dmitry Osipenko wrote: > Currently driver supports legacy power domain API, this patch adds generic > power domain support. This allows us to utilize a modern GENPD API for > newer device-trees. > > Tested-by: Peter Geis # Ouya T30 > Tested-by: Paul Fertser # PAZ00 T20 > Tested-by: Nicolas Chauvet # PAZ00 T20 and TK1 T124 > Tested-by: Matt Merhar # Ouya T30 > Signed-off-by: Dmitry Osipenko Acked-by: Hans Verkuil Regards, Hans > --- > drivers/staging/media/tegra-vde/vde.c | 57 +-- > 1 file changed, 46 insertions(+), 11 deletions(-) > > diff --git a/drivers/staging/media/tegra-vde/vde.c > b/drivers/staging/media/tegra-vde/vde.c > index ed4c1250b303..bb3079a2c0b5 100644 > --- a/drivers/staging/media/tegra-vde/vde.c > +++ b/drivers/staging/media/tegra-vde/vde.c > @@ -20,6 +20,7 @@ > #include > #include > > +#include > #include > > #include "uapi.h" > @@ -920,13 +921,17 @@ static __maybe_unused int > tegra_vde_runtime_suspend(struct device *dev) > struct tegra_vde *vde = dev_get_drvdata(dev); > int err; > > - err = tegra_powergate_power_off(TEGRA_POWERGATE_VDEC); > - if (err) { > - dev_err(dev, "Failed to power down HW: %d\n", err); > - return err; > + if (!dev->pm_domain) { > + err = tegra_powergate_power_off(TEGRA_POWERGATE_VDEC); > + if (err) { > + dev_err(dev, "Failed to power down HW: %d\n", err); > + return err; > + } > } > > clk_disable_unprepare(vde->clk); > + reset_control_release(vde->rst); > + reset_control_release(vde->rst_mc); > > return 0; > } > @@ -936,14 +941,41 @@ static __maybe_unused int > tegra_vde_runtime_resume(struct device *dev) > struct tegra_vde *vde = dev_get_drvdata(dev); > int err; > > - err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_VDEC, > - vde->clk, vde->rst); > + err = reset_control_acquire(vde->rst_mc); > if (err) { > - dev_err(dev, "Failed to power up HW : %d\n", err); > + dev_err(dev, "Failed to acquire mc reset: %d\n", err); > return err; > } > > + err = reset_control_acquire(vde->rst); > + if (err) { > + dev_err(dev, "Failed to acquire reset: %d\n", err); > + goto release_mc_reset; > + } > + > + if (!dev->pm_domain) { > + err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_VDEC, > + vde->clk, vde->rst); > + if (err) { > + dev_err(dev, "Failed to power up HW : %d\n", err); > + goto release_reset; > + } > + } > + > + err = clk_prepare_enable(vde->clk); > + if (err) { > + dev_err(dev, "Failed to enable clock: %d\n", err); > + goto release_reset; > + } > + > return 0; > + > +release_reset: > + reset_control_release(vde->rst); > +release_mc_reset: > + reset_control_release(vde->rst_mc); > + > + return err; > } > > static int tegra_vde_probe(struct platform_device *pdev) > @@ -1001,14 +1033,14 @@ static int tegra_vde_probe(struct platform_device > *pdev) > return err; > } > > - vde->rst = devm_reset_control_get(dev, NULL); > + vde->rst = devm_reset_control_get_exclusive_released(dev, NULL); > if (IS_ERR(vde->rst)) { > err = PTR_ERR(vde->rst); > dev_err(dev, "Could not get VDE reset %d\n", err); > return err; > } > > - vde->rst_mc = devm_reset_control_get_optional(dev, "mc"); > + vde->rst_mc = devm_reset_control_get_optional_exclusive_released(dev, > "mc"); > if (IS_ERR(vde->rst_mc)) { > err = PTR_ERR(vde->rst_mc); > dev_err(dev, "Could not get MC reset %d\n", err); > @@ -1066,6 +1098,10 @@ static int tegra_vde_probe(struct platform_device > *pdev) > pm_runtime_use_autosuspend(dev); > pm_runtime_set_autosuspend_delay(dev, 300); > > + err = devm_tegra_core_dev_init_opp_table_common(dev); > + if (err) > + goto err_pm_runtime; > + > /* >* VDE partition may be left ON after bootloader, hence let's >* power-cycle it in order to put hardware into a predictable lower > @@ -1133,8 +1169,7 @@ static void tegra_vde_shutdown(struct platform_device > *pdev) >* On some devices bootloader isn't ready to a power-gated VDE on >* a warm-reboot, machine will hang in that case. >*/ > - if (pm_runtime_status_suspended(&pdev->dev)) > - tegra_vde_runtime_resume(&pdev->dev); > + pm_runtime_get_sync(&pdev->dev); > } > > static __maybe_unused int tegra_vde_pm_suspend(struct device *dev) >
Re: [PATCH v11 22/34] media: dt: bindings: tegra-vde: Convert to schema
On 12/09/2021 22:08, Dmitry Osipenko wrote: > Convert NVIDIA Tegra video decoder binding to schema. > > Reviewed-by: Rob Herring > Signed-off-by: Dmitry Osipenko Acked-by: Hans Verkuil Regards, Hans > --- > .../bindings/media/nvidia,tegra-vde.txt | 64 --- > .../bindings/media/nvidia,tegra-vde.yaml | 107 ++ > 2 files changed, 107 insertions(+), 64 deletions(-) > delete mode 100644 > Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt > create mode 100644 > Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml > > diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt > b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt > deleted file mode 100644 > index 602169b8aa19.. > --- a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt > +++ /dev/null > @@ -1,64 +0,0 @@ > -NVIDIA Tegra Video Decoder Engine > - > -Required properties: > -- compatible : Must contain one of the following values: > - - "nvidia,tegra20-vde" > - - "nvidia,tegra30-vde" > - - "nvidia,tegra114-vde" > - - "nvidia,tegra124-vde" > - - "nvidia,tegra132-vde" > -- reg : Must contain an entry for each entry in reg-names. > -- reg-names : Must include the following entries: > - - sxe > - - bsev > - - mbe > - - ppe > - - mce > - - tfe > - - ppb > - - vdma > - - frameid > -- iram : Must contain phandle to the mmio-sram device node that represents > - IRAM region used by VDE. > -- interrupts : Must contain an entry for each entry in interrupt-names. > -- interrupt-names : Must include the following entries: > - - sync-token > - - bsev > - - sxe > -- clocks : Must include the following entries: > - - vde > -- resets : Must contain an entry for each entry in reset-names. > -- reset-names : Should include the following entries: > - - vde > - > -Optional properties: > -- resets : Must contain an entry for each entry in reset-names. > -- reset-names : Must include the following entries: > - - mc > -- iommus: Must contain phandle to the IOMMU device node. > - > -Example: > - > -video-codec@6001a000 { > - compatible = "nvidia,tegra20-vde"; > - reg = <0x6001a000 0x1000 /* Syntax Engine */ > -0x6001b000 0x1000 /* Video Bitstream Engine */ > -0x6001c000 0x100 /* Macroblock Engine */ > -0x6001c200 0x100 /* Post-processing Engine */ > -0x6001c400 0x100 /* Motion Compensation Engine */ > -0x6001c600 0x100 /* Transform Engine */ > -0x6001c800 0x100 /* Pixel prediction block */ > -0x6001ca00 0x100 /* Video DMA */ > -0x6001d800 0x300 /* Video frame controls */>; > - reg-names = "sxe", "bsev", "mbe", "ppe", "mce", > - "tfe", "ppb", "vdma", "frameid"; > - iram = <&vde_pool>; /* IRAM region */ > - interrupts = , /* Sync token interrupt > */ > - , /* BSE-V interrupt */ > - ; /* SXE interrupt */ > - interrupt-names = "sync-token", "bsev", "sxe"; > - clocks = <&tegra_car TEGRA20_CLK_VDE>; > - reset-names = "vde", "mc"; > - resets = <&tegra_car 61>, <&mc TEGRA20_MC_RESET_VDE>; > - iommus = <&mc TEGRA_SWGROUP_VDE>; > -}; > diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml > b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml > new file mode 100644 > index ..3b6c1f031e04 > --- /dev/null > +++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml > @@ -0,0 +1,107 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/media/nvidia,tegra-vde.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: NVIDIA Tegra Video Decoder Engine > + > +maintainers: > + - Dmitry Osipenko > + - Jon Hunter > + - Thierry Reding > + > +properties: > + compatible: > +oneOf: > + - items: > + - enum: > + - nvidia,tegra132-vde > + - nvidia,tegra124-vde > + - nvidia,tegra114-vde > + - nvidia,tegra30-vde > + - enum: > + - nvidia,tegra20-vde > + - items: > + - const: nvidia,tegra20-vde > + > + reg: > +maxItems: 9 > + > + reg-names: > +items: > + - const: sxe >
Re: [PATCH v11 23/34] media: dt: bindings: tegra-vde: Document OPP and power domain
On 12/09/2021 22:08, Dmitry Osipenko wrote: > Document new OPP table and power domain properties of the video decoder > hardware. > > Reviewed-by: Rob Herring > Signed-off-by: Dmitry Osipenko Acked-by: Hans Verkuil Regards, Hans > --- > .../devicetree/bindings/media/nvidia,tegra-vde.yaml | 12 > 1 file changed, 12 insertions(+) > > diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml > b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml > index 3b6c1f031e04..0b7d4d815707 100644 > --- a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml > +++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml > @@ -68,6 +68,16 @@ properties: > description: >Phandle of the SRAM MMIO node. > > + operating-points-v2: > +description: > + Should contain freqs and voltages and opp-supported-hw property, > + which is a bitfield indicating SoC speedo or process ID mask. > + > + power-domains: > +maxItems: 1 > +description: > + Phandle to the SoC core power domain. > + > required: >- compatible >- reg > @@ -104,4 +114,6 @@ examples: >reset-names = "vde", "mc"; >resets = <&rst 61>, <&mem 13>; >iommus = <&mem 15>; > + operating-points-v2 = <&dvfs_opp_table>; > + power-domains = <&domain>; > }; >
Re: [PATCH v2 2/2] qcom_scm: hide Kconfig symbol
On 07/10/2021 17:10, Arnd Bergmann wrote: > From: Arnd Bergmann > > Now that SCM can be a loadable module, we have to add another > dependency to avoid link failures when ipa or adreno-gpu are > built-in: > > aarch64-linux-ld: drivers/net/ipa/ipa_main.o: in function `ipa_probe': > ipa_main.c:(.text+0xfc4): undefined reference to `qcom_scm_is_available' > > ld.lld: error: undefined symbol: qcom_scm_is_available >>>> referenced by adreno_gpu.c >>>> gpu/drm/msm/adreno/adreno_gpu.o:(adreno_zap_shader_load) in >>>> archive drivers/built-in.a > > This can happen when CONFIG_ARCH_QCOM is disabled and we don't select > QCOM_MDT_LOADER, but some other module selects QCOM_SCM. Ideally we'd > use a similar dependency here to what we have for QCOM_RPROC_COMMON, > but that causes dependency loops from other things selecting QCOM_SCM. > > This appears to be an endless problem, so try something different this > time: > > - CONFIG_QCOM_SCM becomes a hidden symbol that nothing 'depends on' >but that is simply selected by all of its users > > - All the stubs in include/linux/qcom_scm.h can go away > > - arm-smccc.h needs to provide a stub for __arm_smccc_smc() to >allow compile-testing QCOM_SCM on all architectures. > > - To avoid a circular dependency chain involving RESET_CONTROLLER >and PINCTRL_SUNXI, drop the 'select RESET_CONTROLLER' statement. >According to my testing this still builds fine, and the QCOM >platform selects this symbol already. Acked-by: Hans Verkuil Thanks, Hans > > Acked-by: Kalle Valo > Acked-by: Alex Elder > Signed-off-by: Arnd Bergmann > --- > Changes in v2: > - fix the iommu dependencies > > I've queued this version as a bugfix along with patch 1/2 > in my asm-generic tree. > > drivers/firmware/Kconfig | 5 +- > drivers/gpu/drm/msm/Kconfig| 4 +- > drivers/iommu/Kconfig | 3 +- > drivers/iommu/arm/arm-smmu/Makefile| 3 +- > drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 3 +- > drivers/media/platform/Kconfig | 2 +- > drivers/mmc/host/Kconfig | 2 +- > drivers/net/ipa/Kconfig| 1 + > drivers/net/wireless/ath/ath10k/Kconfig| 2 +- > drivers/pinctrl/qcom/Kconfig | 3 +- > include/linux/arm-smccc.h | 10 +++ > include/linux/qcom_scm.h | 71 -- > 12 files changed, 24 insertions(+), 85 deletions(-) > > diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig > index 220a58cf0a44..cda7d7162cbb 100644 > --- a/drivers/firmware/Kconfig > +++ b/drivers/firmware/Kconfig > @@ -203,10 +203,7 @@ config INTEL_STRATIX10_RSU > Say Y here if you want Intel RSU support. > > config QCOM_SCM > - tristate "Qcom SCM driver" > - depends on ARM || ARM64 > - depends on HAVE_ARM_SMCCC > - select RESET_CONTROLLER > + tristate > > config QCOM_SCM_DOWNLOAD_MODE_DEFAULT > bool "Qualcomm download mode enabled by default" > diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig > index e9c6af78b1d7..3ddf739a6f9b 100644 > --- a/drivers/gpu/drm/msm/Kconfig > +++ b/drivers/gpu/drm/msm/Kconfig > @@ -17,7 +17,7 @@ config DRM_MSM > select DRM_SCHED > select SHMEM > select TMPFS > - select QCOM_SCM if ARCH_QCOM > + select QCOM_SCM > select WANT_DEV_COREDUMP > select SND_SOC_HDMI_CODEC if SND_SOC > select SYNC_FILE > @@ -55,7 +55,7 @@ config DRM_MSM_GPU_SUDO > > config DRM_MSM_HDMI_HDCP > bool "Enable HDMI HDCP support in MSM DRM driver" > - depends on DRM_MSM && QCOM_SCM > + depends on DRM_MSM > default y > help > Choose this option to enable HDCP state machine > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig > index 124c41adeca1..c5c71b7ab7e8 100644 > --- a/drivers/iommu/Kconfig > +++ b/drivers/iommu/Kconfig > @@ -308,7 +308,6 @@ config APPLE_DART > config ARM_SMMU > tristate "ARM Ltd. System MMU (SMMU) Support" > depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64) > - depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y > select IOMMU_API > select IOMMU_IO_PGTABLE_LPAE > select ARM_DMA_USE_IOMMU if ARM > @@ -438,7 +437,7 @@ config QCOM_IOMMU > # Note: iommu drivers cannot (yet?) be built as modules > bool "Qualcomm IOMMU Support" > depends on ARCH_QCOM || (COMPIL
Re: [PATCH v10 00/13] Clean up "mediatek,larb"
Hi Matthias, On 1/17/22 12:49, Matthias Brugger wrote: > > > On 17/01/2022 11:27, AngeloGioacchino Del Regno wrote: >> Il 17/01/22 08:04, Yong Wu ha scritto: >>> MediaTek IOMMU block diagram always like below: >>> >>> M4U >>> | >>> smi-common >>> | >>> - >>> | | ... >>> | | >>> larb1 larb2 >>> | | >>> vdec venc >>> >>> All the consumer connect with smi-larb, then connect with smi-common. >>> >>> When the consumer works, it should enable the smi-larb's power which also >>> need enable the smi-common's power firstly. >>> >>> Thus, Firstly, use the device link connect the consumer and the >>> smi-larbs. then add device link between the smi-larb and smi-common. >>> >>> After adding the device_link, then "mediatek,larb" property can be removed. >>> the iommu consumer don't need call the mtk_smi_larb_get/put to enable >>> the power and clock of smi-larb and smi-common. >>> >>> Base on the media branch [1] and a jpeg dtbinding patchset[2] that already >>> got >>> the necessary R-b. >>> >>> [1] git://linuxtv.org/hverkuil/media_tree.git tags/br-v5.18d >>> [2] >>> https://lore.kernel.org/linux-mediatek/20211206130425.184420-1-hsi...@chromium.org/ >>> >>> Change notes: >>> v10: a) Rebase on the media tree. Respin the "media: mtk-vcodec:" patches. >>> b) Add Joerg's Ack for iommu patches. >>> >>> v9: >>> https://lore.kernel.org/linux-mediatek/2022105509.12010-1-yong...@mediatek.com/ >>> 1) Add return -ENODEV when the dev is null. >>> 2) Add more strict about the case that a iommu consume device use the >>> ports in >>> different larbs. Don't allow this case. >>> 3) Remove two codec interface: mtk_vcodec_release_enc/dec_pm since it >>> only has one >>> line now. >>> >>> v8: >>> https://lore.kernel.org/linux-mediatek/20210929013719.25120-1-yong...@mediatek.com/ >>> 1) Rebase on v5.15-rc1. >>> 2) Don't rebase the below mdp patchset that may still need more >>> discuss. >>> >>> https://lore.kernel.org/linux-mediatek/20210709022324.1607884-1-ei...@chromium.org/ >>> 3) Add Frank's Tested-by. Remove Dafna's Tested-by as he requested. >>> >>> v7: >>> https://lore.kernel.org/linux-mediatek/20210730025238.22456-1-yong...@mediatek.com/ >>> 1) Fix a arm32 boot fail issue. reported from Frank. >>> 2) Add a return fail in the mtk drm. suggested by Dafna. >>> >>> v6: >>> https://lore.kernel.org/linux-mediatek/20210714025626.5528-1-yong...@mediatek.com/ >>> 1) rebase on v5.14-rc1. >>> 2) Fix the issue commented in v5 from Dafna and Hsin-Yi. >>> 3) Remove the patches about using pm_runtime_resume_and_get since they >>> have >>> already been merged by other patches. >>> >>> v5: >>> https://lore.kernel.org/linux-mediatek/20210410091128.31823-1-yong...@mediatek.com/ >>> 1) Base v5.12-rc2. >>> 2) Remove changing the mtk-iommu to module_platform_driver patch, It >>> have already been a >>> independent patch. >>> >>> v4: >>> https://lore.kernel.org/linux-mediatek/1590826218-23653-1-git-send-email-yong...@mediatek.com/ >>> base on v5.7-rc1. >>> 1) Move drm PM patch before smi patchs. >>> 2) Change builtin_platform_driver to module_platform_driver since we may >>> need >>> build as module. >>> 3) Rebase many patchset as above. >>> >>> v3: >>> https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong...@mediatek.com/ >>> 1) rebase on v5.3-rc1 and the latest mt8183 patchset. >>> 2) Use device_is_bound to check whether the driver is ready from >>> Matthias. >>> 3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain >>> the >>> reason in the commit message[3/14]. >>> 4) Add a display patch[12/14] into this series. otherwise it may affect >>> display HW fastlogo even though it don't happen in mt8183. >>> v2: >>> https://lore.kernel.org/linux-iommu/1560171313-28299-1-git-send-email-yong...@mediatek.com/ >>> 1) rebase on v5.2-rc1. >>> 2) Move adding device_link between the consumer and smi-larb into >>> iommu_add_device from Robin. >>> 3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from >>> Evan. >>> 4) Remove the shutdown callback in iommu. >>> >>> v1: >>> https://lore.kernel.org/linux-iommu/1546318276-18993-1-git-send-email-yong...@mediatek.com/ >>> >>> Yong Wu (12): >>> dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW >>> iommu/mediatek-v1: Free the existed fwspec if the master dev already >>> has >>> iommu/mediatek: Return ENODEV if the device is NULL >>> iommu/mediatek: Add probe_defer for smi-larb >>> iommu/mediatek: Add device_link between the consumer and the larb >>> devices >>> media: mtk-jpeg: Get rid of mtk_smi_larb_get/put >>> media: mtk-mdp: Get rid of mtk_smi_larb_get/put >>> drm/mediatek: Get rid of mtk_smi_larb_get/put >>> media: mtk-vcodec: Get rid
Re: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove mtk_vcodec_release_enc_pm
Hi Matthias, On 1/13/22 17:10, Matthias Brugger wrote: > Hi Hans, > > On 13/01/2022 11:15, Hans Verkuil wrote: >> On 13/01/2022 11:11, AngeloGioacchino Del Regno wrote: >>> Il 11/01/22 11:57, AngeloGioacchino Del Regno ha scritto: >>>> Il 12/11/21 11:55, Yong Wu ha scritto: >>>>> After this patchset, mtk_vcodec_release_enc_pm has only one line. >>>>> then remove that function, use pm_runtime_disable instead. >>>>> >>>>> meanwhile, mtk_vcodec_init_enc_pm only operate for the clocks, >>>>> rename it from the _pm to _clk. >>>>> >>>>> No functional change. >>>>> >>>>> CC: Tiffany Lin >>>>> CC: Irui Wang >>>>> Signed-off-by: Yong Wu >>>> >>>> Reviewed-by: AngeloGioacchino Del Regno >>>> >>>> >>> >>> Hello Yong, >>> the mtk-vcodec patches were merged in Yunfei's vcodec patch series and Hans >>> has >>> scheduled that for v5.18. >>> >>> Can you please send a v10 and drop patches 10/15, 11/15, 12/15 (all of the >>> media: mtk-vcodec: *) from this series? >>> >>> For the records, I think that after sending v10 this series is ready to be >>> merged, >>> as it was well reviewed and also tested on many MTK platforms. >> >> Good to know. When I have the v10 I'll try to prioritize reviewing it and >> running >> my usual tests. >> >> Yong, please make sure you run 'checkpatch.pl --strict' over the v10 patches >> and fix >> any issues (using common sense). >> > > Can you please take me in the look when you take the patches. I'll take the > DTS related as soon as you queue up the others. This just got merged into our tree. Regards, Hans
Re: [PATCH v10 00/13] Clean up "mediatek,larb"
On 1/17/22 12:49, Matthias Brugger wrote: > > > On 17/01/2022 11:27, AngeloGioacchino Del Regno wrote: >> Il 17/01/22 08:04, Yong Wu ha scritto: >>> MediaTek IOMMU block diagram always like below: >>> >>> M4U >>> | >>> smi-common >>> | >>> - >>> | | ... >>> | | >>> larb1 larb2 >>> | | >>> vdec venc >>> >>> All the consumer connect with smi-larb, then connect with smi-common. >>> >>> When the consumer works, it should enable the smi-larb's power which also >>> need enable the smi-common's power firstly. >>> >>> Thus, Firstly, use the device link connect the consumer and the >>> smi-larbs. then add device link between the smi-larb and smi-common. >>> >>> After adding the device_link, then "mediatek,larb" property can be removed. >>> the iommu consumer don't need call the mtk_smi_larb_get/put to enable >>> the power and clock of smi-larb and smi-common. >>> >>> Base on the media branch [1] and a jpeg dtbinding patchset[2] that already >>> got >>> the necessary R-b. >>> >>> [1] git://linuxtv.org/hverkuil/media_tree.git tags/br-v5.18d >>> [2] >>> https://lore.kernel.org/linux-mediatek/20211206130425.184420-1-hsi...@chromium.org/ >>> >>> Change notes: >>> v10: a) Rebase on the media tree. Respin the "media: mtk-vcodec:" patches. >>> b) Add Joerg's Ack for iommu patches. >>> >>> v9: >>> https://lore.kernel.org/linux-mediatek/2022105509.12010-1-yong...@mediatek.com/ >>> 1) Add return -ENODEV when the dev is null. >>> 2) Add more strict about the case that a iommu consume device use the >>> ports in >>> different larbs. Don't allow this case. >>> 3) Remove two codec interface: mtk_vcodec_release_enc/dec_pm since it >>> only has one >>> line now. >>> >>> v8: >>> https://lore.kernel.org/linux-mediatek/20210929013719.25120-1-yong...@mediatek.com/ >>> 1) Rebase on v5.15-rc1. >>> 2) Don't rebase the below mdp patchset that may still need more >>> discuss. >>> >>> https://lore.kernel.org/linux-mediatek/20210709022324.1607884-1-ei...@chromium.org/ >>> 3) Add Frank's Tested-by. Remove Dafna's Tested-by as he requested. >>> >>> v7: >>> https://lore.kernel.org/linux-mediatek/20210730025238.22456-1-yong...@mediatek.com/ >>> 1) Fix a arm32 boot fail issue. reported from Frank. >>> 2) Add a return fail in the mtk drm. suggested by Dafna. >>> >>> v6: >>> https://lore.kernel.org/linux-mediatek/20210714025626.5528-1-yong...@mediatek.com/ >>> 1) rebase on v5.14-rc1. >>> 2) Fix the issue commented in v5 from Dafna and Hsin-Yi. >>> 3) Remove the patches about using pm_runtime_resume_and_get since they >>> have >>> already been merged by other patches. >>> >>> v5: >>> https://lore.kernel.org/linux-mediatek/20210410091128.31823-1-yong...@mediatek.com/ >>> 1) Base v5.12-rc2. >>> 2) Remove changing the mtk-iommu to module_platform_driver patch, It >>> have already been a >>> independent patch. >>> >>> v4: >>> https://lore.kernel.org/linux-mediatek/1590826218-23653-1-git-send-email-yong...@mediatek.com/ >>> base on v5.7-rc1. >>> 1) Move drm PM patch before smi patchs. >>> 2) Change builtin_platform_driver to module_platform_driver since we may >>> need >>> build as module. >>> 3) Rebase many patchset as above. >>> >>> v3: >>> https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong...@mediatek.com/ >>> 1) rebase on v5.3-rc1 and the latest mt8183 patchset. >>> 2) Use device_is_bound to check whether the driver is ready from >>> Matthias. >>> 3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain >>> the >>> reason in the commit message[3/14]. >>> 4) Add a display patch[12/14] into this series. otherwise it may affect >>> display HW fastlogo even though it don't happen in mt8183. >>> v2: >>> https://lore.kernel.org/linux-iommu/1560171313-28299-1-git-send-email-yong...@mediatek.com/ >>> 1) rebase on v5.2-rc1. >>> 2) Move adding device_link between the consumer and smi-larb into >>> iommu_add_device from Robin. >>> 3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from >>> Evan. >>> 4) Remove the shutdown callback in iommu. >>> >>> v1: >>> https://lore.kernel.org/linux-iommu/1546318276-18993-1-git-send-email-yong...@mediatek.com/ >>> >>> Yong Wu (12): >>> dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW >>> iommu/mediatek-v1: Free the existed fwspec if the master dev already >>> has >>> iommu/mediatek: Return ENODEV if the device is NULL >>> iommu/mediatek: Add probe_defer for smi-larb >>> iommu/mediatek: Add device_link between the consumer and the larb >>> devices >>> media: mtk-jpeg: Get rid of mtk_smi_larb_get/put >>> media: mtk-mdp: Get rid of mtk_smi_larb_get/put >>> drm/mediatek: Get rid of mtk_smi_larb_get/put >>> media: mtk-vcodec: Get rid of mtk_smi_
[PATCH] drm/nouveau: hdmigv100.c: fix corrupted HDMI Vendor InfoFrame
gv100_hdmi_ctrl() writes vendor_infoframe.subpack0_high to 0x6f0110, and then overwrites it with 0. Just drop the overwrite with 0, that's clearly a mistake. Because of this issue the HDMI VIC is 0 instead of 1 in the HDMI Vendor InfoFrame when transmitting 4kp30. Signed-off-by: Hans Verkuil Fixes: 290ffeafcc1a (drm/nouveau/disp/gv100: initial support) --- diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c index 6e3c450eaace..3ff49344abc7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c @@ -62,7 +62,6 @@ gv100_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet, nvkm_wr32(device, 0x6f0108 + hdmi, vendor_infoframe.header); nvkm_wr32(device, 0x6f010c + hdmi, vendor_infoframe.subpack0_low); nvkm_wr32(device, 0x6f0110 + hdmi, vendor_infoframe.subpack0_high); - nvkm_wr32(device, 0x6f0110 + hdmi, 0x); nvkm_wr32(device, 0x6f0114 + hdmi, 0x); nvkm_wr32(device, 0x6f0118 + hdmi, 0x); nvkm_wr32(device, 0x6f011c + hdmi, 0x);
[PATCH] drm/nouveau: set RGB quantization range to FULL
The nouveau driver outputs full range RGB, but the AVI InfoFrame just says 'Default' instead of 'Full'. Call drm_hdmi_avi_infoframe_quant_range to fill in the quantization field of the AVI InfoFrame correctly. Now displays that advertise RGB Selectable Quantization Range in their EDID will understand that full range is transmitted by the HDMI output. This is consistent to how the Nvidia's driver behaves. Signed-off-by: Hans Verkuil --- diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index d7b9f7f8c9e3..b05c01927fe6 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -852,6 +852,9 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc, ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, &nv_connector->base, mode); if (!ret) { + drm_hdmi_avi_infoframe_quant_range(&avi_frame.avi, + &nv_connector->base, mode, + HDMI_QUANTIZATION_RANGE_FULL); /* We have an AVI InfoFrame, populate it to the display */ args.pwr.avi_infoframe_length = hdmi_infoframe_pack(&avi_frame, args.infoframes, 17);
Re: [PATCH v9 00/15] Clean up "mediatek,larb"
Hi Yong Wu, On 12/11/2021 11:54, Yong Wu wrote: > MediaTek IOMMU block diagram always like below: > > M4U > | > smi-common > | > - > | | ... > | | > larb1 larb2 > | | > vdec venc > > All the consumer connect with smi-larb, then connect with smi-common. > > When the consumer works, it should enable the smi-larb's power which also > need enable the smi-common's power firstly. > > Thus, Firstly, use the device link connect the consumer and the > smi-larbs. then add device link between the smi-larb and smi-common. > > After adding the device_link, then "mediatek,larb" property can be removed. > the iommu consumer don't need call the mtk_smi_larb_get/put to enable > the power and clock of smi-larb and smi-common. > > Base on a jpeg dt-bing patchset[1] that already got the necessary R-b. > > This patchset cross several tree, From [2], the media tree should be a good > choice. > > [1] > https://lore.kernel.org/linux-mediatek/20210702102304.3346429-1-hsi...@chromium.org/ Please resend this patch series converting the jpeg bindings to yaml, and this time CC the linux-media mailinglist. Because that was omitted, it never appeared in the media patchwork system, and so this was never merged. Since this patch series depends on this series, this needs to be merged first. Bindings for media drivers must be CC-ed to linux-media, since we maintain those. Regards, Hans > [2] > https://lore.kernel.org/linux-mediatek/e7269c80-5437-6ab9-c1db-df0b94eb9...@gmail.com/ > > Change notes: > v9: 1) Add return -ENODEV when the dev is null. > 2) Add more strict about the case that a iommu consume device use the > ports in > different larbs. Don't allow this case. > 3) Remove two codec interface: mtk_vcodec_release_enc/dec_pm since it > only has one > line now. > > v8: > https://lore.kernel.org/linux-mediatek/20210929013719.25120-1-yong...@mediatek.com/ > 1) Rebase on v5.15-rc1. > 2) Don't rebase the below mdp patchset that may still need more discuss. > > https://lore.kernel.org/linux-mediatek/20210709022324.1607884-1-ei...@chromium.org/ > 3) Add Frank's Tested-by. Remove Dafna's Tested-by as he requested. > > v7: > https://lore.kernel.org/linux-mediatek/20210730025238.22456-1-yong...@mediatek.com/ > 1) Fix a arm32 boot fail issue. reported from Frank. > 2) Add a return fail in the mtk drm. suggested by Dafna. > > v6: > https://lore.kernel.org/linux-mediatek/20210714025626.5528-1-yong...@mediatek.com/ > 1) rebase on v5.14-rc1. > 2) Fix the issue commented in v5 from Dafna and Hsin-Yi. > 3) Remove the patches about using pm_runtime_resume_and_get since they > have >already been merged by other patches. > > v5: > https://lore.kernel.org/linux-mediatek/20210410091128.31823-1-yong...@mediatek.com/ > 1) Base v5.12-rc2. > 2) Remove changing the mtk-iommu to module_platform_driver patch, It have > already been a > independent patch. > > v4: > https://lore.kernel.org/linux-mediatek/1590826218-23653-1-git-send-email-yong...@mediatek.com/ > > base on v5.7-rc1. > 1) Move drm PM patch before smi patchs. > 2) Change builtin_platform_driver to module_platform_driver since we may > need > build as module. > 3) Rebase many patchset as above. > > v3: > https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong...@mediatek.com/ > 1) rebase on v5.3-rc1 and the latest mt8183 patchset. > 2) Use device_is_bound to check whether the driver is ready from > Matthias. > 3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain the >reason in the commit message[3/14]. > 4) Add a display patch[12/14] into this series. otherwise it may affect >display HW fastlogo even though it don't happen in mt8183. > > v2: > https://lore.kernel.org/linux-iommu/1560171313-28299-1-git-send-email-yong...@mediatek.com/ >1) rebase on v5.2-rc1. >2) Move adding device_link between the consumer and smi-larb into > iommu_add_device from Robin. >3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from > Evan. >4) Remove the shutdown callback in iommu. > > v1: > https://lore.kernel.org/linux-iommu/1546318276-18993-1-git-send-email-yong...@mediatek.com/ > > Yong Wu (14): > dt-binding: mediatek: Get rid of mediatek, larb for multimedia HW > iommu/mediatek-v1: Free the existed fwspec if the master dev already > has > iommu/mediatek: Return ENODEV if the device is NULL > iommu/mediatek: Add probe_defer for smi-larb > iommu/mediatek: Add device_link between the consumer and the larb > devices > media: mtk-jpeg: Get rid of mtk_smi_larb_get/put > media: mtk-mdp: Get rid of mtk_smi_larb_get/put > drm/mediatek: Get rid of mtk_smi_larb_get/put > media: mtk-vcodec: Get rid of mtk_smi_larb_get/put > media: mtk-vcodec: dec: Remove mtk_vcodec_release_dec_pm
Re: [PATCH v9 00/15] Clean up "mediatek,larb"
On 06/12/2021 12:52, Joerg Roedel wrote: > On Fri, Nov 12, 2021 at 06:54:54PM +0800, Yong Wu wrote: >> Yong Wu (14): >> dt-binding: mediatek: Get rid of mediatek, larb for multimedia HW >> iommu/mediatek-v1: Free the existed fwspec if the master dev already >> has >> iommu/mediatek: Return ENODEV if the device is NULL >> iommu/mediatek: Add probe_defer for smi-larb >> iommu/mediatek: Add device_link between the consumer and the larb >> devices >> media: mtk-jpeg: Get rid of mtk_smi_larb_get/put >> media: mtk-mdp: Get rid of mtk_smi_larb_get/put >> drm/mediatek: Get rid of mtk_smi_larb_get/put >> media: mtk-vcodec: Get rid of mtk_smi_larb_get/put >> media: mtk-vcodec: dec: Remove mtk_vcodec_release_dec_pm >> media: mtk-vcodec: enc: Remove mtk_vcodec_release_enc_pm >> memory: mtk-smi: Get rid of mtk_smi_larb_get/put >> arm: dts: mediatek: Get rid of mediatek, larb for MM nodes >> arm64: dts: mediatek: Get rid of mediatek, larb for MM nodes >> >> Yongqiang Niu (1): >> drm/mediatek: Add pm runtime support for ovl and rdma > > What is the plan for merging this? If Matthias has no objections I can > take the iommu-parts, or will this go through another tree? I think it might be easiest if it is all going through the media subsystem (except for the dts patches, we don't handle those unless specifically requested to do so). I need a resend for jpeg bindings txt to yaml conversion series first, though. This time with the linux-media mailinglist included :-) I would need your Ack for the iommu patches as well, of course. Regards, Hans
Re: [PATCH 00/15] drm/vc4: hdmi: Add CEC support for the BCM2711
Hi Maxime, On 10/12/2020 14:46, Maxime Ripard wrote: > Hi, > > Here's a series introducing the CEC support for the BCM2711 found on the > RaspberryPi4. > > The BCM2711 HDMI controller uses a similar layout for the CEC registers, the > main difference being that the interrupt handling part is now shared between > both HDMI controllers. > > This series is mainly about fixing a couple of bugs, reworking the driver to > support having two different interrupts, one for each direction, provided by > an > external irqchip, and enables the irqchip driver for the controller we have. > > This has been tested on an RPi3 and RPi4, but requires the latest firmware. > It's is based on the 10 and 12 bpc series. This series looks good to me. Before I give my Acked-by for this series, can you confirm that it is possible to transmit the Image View On message on both outputs of the RPi4 when the HPD is low? See section "CEC Without HPD" in https://hverkuil.home.xs4all.nl/cec-status.txt on how to test this with a Pulse-Eight device. This should work. Regards, Hans > > Here is the cec-compliance output: > > $ cec-ctl --tuner -p 1.0.0.0 > The CEC adapter doesn't allow setting the physical address manually, ignore > this option. > > Driver Info: > Driver Name: vc4_hdmi > Adapter Name : vc4 > Capabilities : 0x010e > Logical Addresses > Transmit > Passthrough > Driver version : 5.10.0 > Available Logical Addresses: 1 > Physical Address : 1.0.0.0 > Logical Address Mask : 0x0008 > CEC Version: 2.0 > Vendor ID : 0x000c03 (HDMI) > OSD Name : Tuner > Logical Addresses : 1 (Allow RC Passthrough) > > Logical Address : 3 (Tuner 1) > Primary Device Type: Tuner > Logical Address Type : Tuner > All Device Types : Tuner > RC TV Profile : None > Device Features: > None > > $ cec-compliance > cec-compliance SHA : not available > Driver Info: > Driver Name: vc4_hdmi > Adapter Name : vc4 > Capabilities : 0x010e > Logical Addresses > Transmit > Passthrough > Driver version : 5.10.0 > Available Logical Addresses: 1 > Physical Address : 1.0.0.0 > Logical Address Mask : 0x0008 > CEC Version: 2.0 > Vendor ID : 0x000c03 (HDMI) > OSD Name : Tuner > Logical Addresses : 1 (Allow RC Passthrough) > > Logical Address : 3 (Tuner 1) > Primary Device Type: Tuner > Logical Address Type : Tuner > All Device Types : Tuner > RC TV Profile : None > Device Features: > None > > Compliance test for vc4_hdmi device /dev/cec0: > > The test results mean the following: > OK Supported correctly by the device. > OK (Not Supported) Not supported and not mandatory for the device. > OK (Presumed) Presumably supported. Manually check to confirm. > OK (Unexpected) Supported correctly but is not expected to be > supported for this device. > OK (Refused)Supported by the device, but was refused. > FAILFailed and was expected to be supported by this > device. > > Find remote devices: > Polling: OK > > Network topology: > System Information for device 0 (TV) from device 3 (Tuner 1): > CEC Version: 2.0 > Physical Address : 0.0.0.0 > Primary Device Type: TV > Vendor ID : 0x000c03 (HDMI) > OSD Name : 'test-124' > Power Status : Tx, OK, Rx, OK, Feature Abort > > Total for vc4_hdmi device /dev/cec0: 1, Succeeded: 1, Failed: 0, Warnings: 0 > > Let me know what you think, > Maxime > > Dom Cobley (5): > drm/vc4: hdmi: Move hdmi reset to bind > drm/vc4: hdmi: Fix register offset with longer CEC messages > drm/vc4: hdmi: Fix up CEC registers > drm/vc4: hdmi: Restore cec physical address on reconnect > drm/vc4: hdmi: Remove cec_available flag > > Maxime Ripard (10): > irqchip: Allow to compile bcmstb on other platforms > drm/vc4: hdmi: Compute the CEC clock divider from the clock rate > drm/vc4: hdmi: Update the CEC clock divider on HSM rate change > drm/vc4: hdmi: Introduce a CEC clock > drm/vc4: hdmi: Split the interrupt handlers > drm/vc4: hdmi: Support BCM2711 CEC interrupt setup > drm/vc4: hdmi: Don't register the CEC adapter if there's no i
Re: [PATCH 00/15] drm/vc4: hdmi: Add CEC support for the BCM2711
On 17/12/2020 11:49, Maxime Ripard wrote: > Hi Hans, > > On Wed, Dec 16, 2020 at 01:35:43PM +0100, Hans Verkuil wrote: >> Hi Maxime, >> >> On 10/12/2020 14:46, Maxime Ripard wrote: >>> Hi, >>> >>> Here's a series introducing the CEC support for the BCM2711 found on the >>> RaspberryPi4. >>> >>> The BCM2711 HDMI controller uses a similar layout for the CEC registers, the >>> main difference being that the interrupt handling part is now shared between >>> both HDMI controllers. >>> >>> This series is mainly about fixing a couple of bugs, reworking the driver to >>> support having two different interrupts, one for each direction, provided >>> by an >>> external irqchip, and enables the irqchip driver for the controller we have. >>> >>> This has been tested on an RPi3 and RPi4, but requires the latest firmware. >>> It's is based on the 10 and 12 bpc series. >> >> This series looks good to me. Before I give my Acked-by for this series, can >> you >> confirm that it is possible to transmit the Image View On message on both >> outputs >> of the RPi4 when the HPD is low? >> >> See section "CEC Without HPD" in >> https://hverkuil.home.xs4all.nl/cec-status.txt >> on how to test this with a Pulse-Eight device. >> >> This should work. > > This is the output on the RPi4: > > # cec-ctl --playback > Driver Info: > Driver Name: vc4_hdmi > Adapter Name : vc4 > Capabilities : 0x010e > Logical Addresses > Transmit > Passthrough > Driver version : 5.10.0 > Available Logical Addresses: 1 > Physical Address : f.f.f.f > Logical Address Mask : 0x > CEC Version: 2.0 > Vendor ID : 0x000c03 (HDMI) > OSD Name : Playback > Logical Addresses : 1 (Allow RC Passthrough) > > Logical Address : Not Allocated > Primary Device Type: Playback > Logical Address Type : Playback > All Device Types : Playback > RC TV Profile : None > Device Features: > None > > # cec-ctl -t0 --image-view-on > Driver Info: > Driver Name: vc4_hdmi > Adapter Name : vc4 > Capabilities : 0x010e > Logical Addresses > Transmit > Passthrough > Driver version : 5.10.0 > Available Logical Addresses: 1 > Physical Address : f.f.f.f > Logical Address Mask : 0x > CEC Version: 2.0 > Vendor ID : 0x000c03 (HDMI) > OSD Name : Playback > Logical Addresses : 1 (Allow RC Passthrough) > > Logical Address : Not Allocated > Primary Device Type: Playback > Logical Address Type : Playback > All Device Types : Playback > RC TV Profile : None > Device Features: > None > > > Transmit from Unregistered to TV (15 to 0): > CEC_MSG_IMAGE_VIEW_ON (0x04) > Sequence: 1 Tx Timestamp: 77.631s > > > And this is the output on my desktop with the Pulse-Eight: > $ sudo cec-ctl -p0.0.0.0 --tv > Driver Info: > Driver Name: pulse8-cec > Adapter Name : serio0 > Capabilities : 0x003f > Physical Address > Logical Addresses > Transmit > Passthrough > Remote Control Support > Monitor All > Driver version : 5.9.8 > Available Logical Addresses: 1 > Connector Info : None > Physical Address : 0.0.0.0 > Logical Address Mask : 0x0001 > CEC Version: 2.0 > Vendor ID : 0x000c03 (HDMI) > OSD Name : 'TV ' > Logical Addresses : 1 (Allow RC Passthrough) > > Logical Address : 0 (TV) > Primary Device Type: TV > Logical Address Type : TV > All Device Types : TV > RC TV Profile : None > Device Features: > None > > $ sudo cec-ctl -M > Driver Info: > Dr
Re: [PATCH v3 1/4] dp/dp_mst: Add support for sink event notify messages
Hi Sam, This series still hasn't been merged. It still applies cleanly to v5.11-rc1. Daniel, can you merge this series for 5.12? Or Ack this series so I can merge it? The first three patches deal with DP MST support, and this needs review from you or David. Regards, Hans On 23/09/2020 04:13, Sam McNally wrote: > Sink event notify messages are used for MST CEC IRQs. Add parsing > support for sink event notify messages in preparation for handling MST > CEC IRQs. > > Signed-off-by: Sam McNally > --- > > (no changes since v1) > > drivers/gpu/drm/drm_dp_mst_topology.c | 37 ++- > include/drm/drm_dp_mst_helper.h | 14 ++ > 2 files changed, 50 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c > b/drivers/gpu/drm/drm_dp_mst_topology.c > index 17dbed0a9800..15b6cc39a754 100644 > --- a/drivers/gpu/drm/drm_dp_mst_topology.c > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c > @@ -1027,6 +1027,30 @@ static bool > drm_dp_sideband_parse_resource_status_notify(struct drm_dp_sideband_ > return false; > } > > +static bool drm_dp_sideband_parse_sink_event_notify( > + struct drm_dp_sideband_msg_rx *raw, > + struct drm_dp_sideband_msg_req_body *msg) > +{ > + int idx = 1; > + > + msg->u.sink_event.port_number = (raw->msg[idx] & 0xf0) >> 4; > + idx++; > + if (idx > raw->curlen) > + goto fail_len; > + > + memcpy(msg->u.sink_event.guid, &raw->msg[idx], 16); > + idx += 16; > + if (idx > raw->curlen) > + goto fail_len; > + > + msg->u.sink_event.event_id = (raw->msg[idx] << 8) | (raw->msg[idx + 1]); > + idx++; > + return true; > +fail_len: > + DRM_DEBUG_KMS("sink event notify parse length fail %d %d\n", idx, > raw->curlen); > + return false; > +} > + > static bool drm_dp_sideband_parse_req(struct drm_dp_sideband_msg_rx *raw, > struct drm_dp_sideband_msg_req_body *msg) > { > @@ -1038,6 +1062,8 @@ static bool drm_dp_sideband_parse_req(struct > drm_dp_sideband_msg_rx *raw, > return drm_dp_sideband_parse_connection_status_notify(raw, msg); > case DP_RESOURCE_STATUS_NOTIFY: > return drm_dp_sideband_parse_resource_status_notify(raw, msg); > + case DP_SINK_EVENT_NOTIFY: > + return drm_dp_sideband_parse_sink_event_notify(raw, msg); > default: > DRM_ERROR("Got unknown request 0x%02x (%s)\n", msg->req_type, > drm_dp_mst_req_type_str(msg->req_type)); > @@ -3875,6 +3901,8 @@ drm_dp_mst_process_up_req(struct > drm_dp_mst_topology_mgr *mgr, > guid = msg->u.conn_stat.guid; > else if (msg->req_type == DP_RESOURCE_STATUS_NOTIFY) > guid = msg->u.resource_stat.guid; > + else if (msg->req_type == DP_SINK_EVENT_NOTIFY) > + guid = msg->u.sink_event.guid; > > if (guid) > mstb = drm_dp_get_mst_branch_device_by_guid(mgr, guid); > @@ -3948,7 +3976,8 @@ static int drm_dp_mst_handle_up_req(struct > drm_dp_mst_topology_mgr *mgr) > drm_dp_sideband_parse_req(&mgr->up_req_recv, &up_req->msg); > > if (up_req->msg.req_type != DP_CONNECTION_STATUS_NOTIFY && > - up_req->msg.req_type != DP_RESOURCE_STATUS_NOTIFY) { > + up_req->msg.req_type != DP_RESOURCE_STATUS_NOTIFY && > + up_req->msg.req_type != DP_SINK_EVENT_NOTIFY) { > DRM_DEBUG_KMS("Received unknown up req type, ignoring: %x\n", > up_req->msg.req_type); > kfree(up_req); > @@ -3976,6 +4005,12 @@ static int drm_dp_mst_handle_up_req(struct > drm_dp_mst_topology_mgr *mgr) > DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", > res_stat->port_number, > res_stat->available_pbn); > + } else if (up_req->msg.req_type == DP_SINK_EVENT_NOTIFY) { > + const struct drm_dp_sink_event_notify *sink_event = > + &up_req->msg.u.sink_event; > + > + DRM_DEBUG_KMS("Got SEN: pn: %d event_id %d\n", > + sink_event->port_number, sink_event->event_id); > } > > up_req->hdr = mgr->up_req_recv.initial_hdr; > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h > index 6ae5860d8644..c7c79e0ced18 100644 > --- a/include/drm/drm_dp_mst_helper.h > +++ b/include/drm/drm_dp_mst_helper.h > @@ -402,6 +402,19 @@ struct drm_dp_resource_status_notify { > u16 available_pbn; > }; > > +#define DP_SINK_EVENT_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERRORBIT(0) > +#define DP_SINK_EVENT_PANEL_REPLAY_RFB_STORAGE_ERROR BIT(1) > +#define DP_SINK_EVENT_DSC_RC_BUFFER_UNDER_RUNBIT(2) > +#define DP_SINK_EVENT_DSC_RC_BUFFER_OVERFLOW BIT(3) > +#define DP_SINK_EVENT_DSC_CHUNK_LENGTH_ERROR BIT(4) > +#de
Re: [PATCH v2 00/15] drm/vc4: hdmi: Add CEC support for the BCM2711
Hi Maxime, On 11/01/2021 15:22, Maxime Ripard wrote: > Hi, > > Here's a series introducing the CEC support for the BCM2711 found on the > RaspberryPi4. > > The BCM2711 HDMI controller uses a similar layout for the CEC registers, the > main difference being that the interrupt handling part is now shared between > both HDMI controllers. > > This series is mainly about fixing a couple of bugs, reworking the driver to > support having two different interrupts, one for each direction, provided by > an > external irqchip, and enables the irqchip driver for the controller we have. > > This has been tested on an RPi3 and RPi4, but requires the latest firmware. > It's is based on the 10 and 12 bpc series. Thank you for this series, I plan to test this later this week. Regards, Hans > > Here is the cec-compliance output: > > pi@raspberrypi:~$ cec-ctl --tuner -p 1.0.0.0 > The CEC adapter doesn't allow setting the physical address manually, ignore > this option. > > Driver Info: > Driver Name: vc4_hdmi > Adapter Name : vc4 > Capabilities : 0x010e > Logical Addresses > Transmit > Passthrough > Driver version : 5.10.0 > Available Logical Addresses: 1 > Physical Address : 1.0.0.0 > Logical Address Mask : 0x0008 > CEC Version: 2.0 > Vendor ID : 0x000c03 (HDMI) > OSD Name : Tuner > Logical Addresses : 1 (Allow RC Passthrough) > > Logical Address : 3 (Tuner 1) > Primary Device Type: Tuner > Logical Address Type : Tuner > All Device Types : Tuner > RC TV Profile : None > Device Features: > None > > pi@raspberrypi:~$ cec-compliance > cec-compliance SHA : not available > Driver Info: > Driver Name: vc4_hdmi > Adapter Name : vc4 > Capabilities : 0x010e > Logical Addresses > Transmit > Passthrough > Driver version : 5.10.0 > Available Logical Addresses: 1 > Physical Address : 1.0.0.0 > Logical Address Mask : 0x0008 > CEC Version: 2.0 > Vendor ID : 0x000c03 (HDMI) > OSD Name : Tuner > Logical Addresses : 1 (Allow RC Passthrough) > > Logical Address : 3 (Tuner 1) > Primary Device Type: Tuner > Logical Address Type : Tuner > All Device Types : Tuner > RC TV Profile : None > Device Features: > None > > Compliance test for device /dev/cec0: > > The test results mean the following: > OK Supported correctly by the device. > OK (Not Supported) Not supported and not mandatory for the device. > OK (Presumed) Presumably supported. Manually check to confirm. > OK (Unexpected) Supported correctly but is not expected to be > supported for this device. > OK (Refused)Supported by the device, but was refused. > FAILFailed and was expected to be supported by this > device. > > Find remote devices: > Polling: OK > > Network topology: > System Information for device 0 (TV) from device 3 (Tuner 1): > CEC Version: 2.0 > Physical Address : 0.0.0.0 > Primary Device Type: TV > Vendor ID : 0x000c03 > OSD Name : 'TV ' > Power Status : Tx, OK, Rx, OK, Feature Abort > > Total: 1, Succeeded: 1, Failed: 0, Warnings: 0 > > pi@raspberrypi:~$ cec-ctl -d1 --tuner -p 1.0.0.0 > The CEC adapter doesn't allow setting the physical address manually, ignore > this option. > > Driver Info: > Driver Name: vc4_hdmi > Adapter Name : vc4 > Capabilities : 0x010e > Logical Addresses > Transmit > Passthrough > Driver version : 5.10.0 > Available Logical Addresses: 1 > Physical Address : 1.0.0.0 > Logical Address Mask : 0x0008 > CEC Version: 2.0 > Vendor ID : 0x000c03 (HDMI) > OSD Name : Tuner > Logical Addresses : 1 (Allow RC Passthrough) > > Logical Address : 3 (Tuner 1) > Primary Device Type: Tuner > Logical Address Type : Tuner > All Device Types : Tuner > RC TV Profile : None > Device Features: > None
Re: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove mtk_vcodec_release_enc_pm
On 13/01/2022 11:11, AngeloGioacchino Del Regno wrote: > Il 11/01/22 11:57, AngeloGioacchino Del Regno ha scritto: >> Il 12/11/21 11:55, Yong Wu ha scritto: >>> After this patchset, mtk_vcodec_release_enc_pm has only one line. >>> then remove that function, use pm_runtime_disable instead. >>> >>> meanwhile, mtk_vcodec_init_enc_pm only operate for the clocks, >>> rename it from the _pm to _clk. >>> >>> No functional change. >>> >>> CC: Tiffany Lin >>> CC: Irui Wang >>> Signed-off-by: Yong Wu >> >> Reviewed-by: AngeloGioacchino Del Regno >> >> > > Hello Yong, > the mtk-vcodec patches were merged in Yunfei's vcodec patch series and Hans > has > scheduled that for v5.18. > > Can you please send a v10 and drop patches 10/15, 11/15, 12/15 (all of the > media: mtk-vcodec: *) from this series? > > For the records, I think that after sending v10 this series is ready to be > merged, > as it was well reviewed and also tested on many MTK platforms. Good to know. When I have the v10 I'll try to prioritize reviewing it and running my usual tests. Yong, please make sure you run 'checkpatch.pl --strict' over the v10 patches and fix any issues (using common sense). Regards, Hans > > Thank you, > - Angelo
[PATCHv15 15/15] cec: add ARC and CDC support
From: Hans Verkuil Preliminary ARC and CDC support. Untested and experimental! Signed-off-by: Hans Verkuil --- .../DocBook/media/v4l/cec-ioc-adap-g-caps.xml | 10 ++ Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml | 36 Documentation/cec.txt | 75 drivers/staging/media/cec/cec.c| 198 - include/linux/cec.h| 5 + include/media/cec.h| 12 ++ 6 files changed, 334 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml b/Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml index b99ed22..65250b7 100644 --- a/Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml +++ b/Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml @@ -129,6 +129,16 @@ The CEC hardware can monitor all messages, not just directed and broadcast messages. + + CEC_CAP_ARC + 0x0040 + This adapter supports the Audio Return Channel protocol. + + + CEC_CAP_CDC_HPD + 0x0080 + This adapter supports the hotplug detect protocol over CDC. + diff --git a/Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml b/Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml index 0cb1941..485e8b2 100644 --- a/Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml +++ b/Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml @@ -187,6 +187,42 @@ The follower can of course always call &CEC-TRANSMIT;. &cs-def; + CEC_MSG_INITIATE_ARC + + + + CEC_MSG_TERMINATE_ARC + + + + CEC_MSG_REQUEST_ARC_INITIATION + + + + CEC_MSG_REQUEST_ARC_TERMINATION + + + + CEC_MSG_REPORT_ARC_INITIATED + + + + CEC_MSG_REPORT_ARC_TERMINATED + If CEC_CAP_ARC is not set, then just pass + it on to userspace for processing. However, if CEC_CAP_ARC is + set, then the core framework processes this message and userspace will + not see it, not even in passthrough mode. + + + CEC_MSG_CDC_MESSAGE + If CEC_CAP_CDC_HPD is not set, then just pass + it on to userspace for processing. Do the same if the CDC command is not + one of CEC_MSG_CDC_HPD_REPORT_STATE or + CEC_MSG_CDC_HPD_SET_STATE. Else the core framework + processes this message and userspace will not see it, not even in passthrough + mode. + + CEC_MSG_GET_CEC_VERSION When in passthrough mode this message has to be handled by userspace, otherwise the core will return the CEC version that was set with &CEC-ADAP-S-LOG-ADDRS;. diff --git a/Documentation/cec.txt b/Documentation/cec.txt index 75155fe..8a61819 100644 --- a/Documentation/cec.txt +++ b/Documentation/cec.txt @@ -216,6 +216,16 @@ struct cec_adap_ops { /* High-level CEC message callback */ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); + + /* High-level CDC Hotplug Detect callbacks */ + u8 (*source_cdc_hpd)(struct cec_adapter *adap, u8 cdc_hpd_state); + void (*sink_cdc_hpd)(struct cec_adapter *adap, u8 cdc_hpd_state, u8 cdc_hpd_error); + + /* High-level Audio Return Channel callbacks */ + int (*sink_initiate_arc)(struct cec_adapter *adap); + int (*sink_terminate_arc)(struct cec_adapter *adap); + int (*source_arc_initiated)(struct cec_adapter *adap); + int (*source_arc_terminated)(struct cec_adapter *adap); }; The received() callback allows the driver to optionally handle a newly @@ -228,6 +238,62 @@ callback. If it doesn't want to handle this message, then it should return -ENOMSG, otherwise the CEC framework assumes it processed this message and it will not no anything with it. +The other callbacks deal with two CEC features: CDC Hotplug Detect and +Audio Return Channel. Here the framework takes care of handling these +messages and it calls the callbacks to notify the driver when it needs +to take action. + +CDC Hotplug Support +--- + +A source received a hotplug state change message: + + u8 (*source_cdc_hpd)(struct cec_adapter *adap, u8 cdc_hpd_state); + +A source received a CEC_MSG_CDC_HPD_SET_STATE message. The framework will +reply with a CEC_MSG_CDC_HPD_REPORT_STATE message and this callback is used +to fill in the HPD Error Code Operand of the REPORT_STATE message. In addition, +the driver can act in this callback on the hotplug state change. + +Only implement if CEC_CAP_CDC_HPD is set. + +A sink received a hotplug report state message: + + void (*sink_cdc_hpd)(struct cec_
[RFC PATCH 0/3] OMAP4 HDMI CEC support
From: Hans Verkuil This patch series sits on top of my earlier HDMI CEC framework: http://www.spinics.net/lists/linux-media/msg99847.html It is an RFC patch for now as I want to clean up hdmi_cec a bit more and do a bit more testing. Many thanks to Tomi for finding obscure problems in the omap4 drivers that prevented CEC from working on my pandaboard. Feedback is welcome! Regards, Hans Hans Verkuil (2): omap4: add CEC support encoder-tpd12s015: keep the ls_oe_gpio on while the phys_addr is valid Tomi Valkeinen (1): drm/omap: fix OMAP4 hdmi_core_powerdown_disable() arch/arm/boot/dts/omap4-panda-a4.dts | 2 +- arch/arm/boot/dts/omap4-panda-es.dts | 2 +- arch/arm/boot/dts/omap4.dtsi | 5 +- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 13 +- drivers/gpu/drm/omapdrm/dss/Kconfig| 8 + drivers/gpu/drm/omapdrm/dss/Makefile | 3 + drivers/gpu/drm/omapdrm/dss/hdmi.h | 62 +++- drivers/gpu/drm/omapdrm/dss/hdmi4.c| 39 ++- drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | 2 +- drivers/gpu/drm/omapdrm/dss/hdmi_cec.c | 329 + 10 files changed, 454 insertions(+), 11 deletions(-) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi_cec.c -- 2.8.1
[RFC PATCH 2/3] omap4: add CEC support
From: Hans Verkuil Signed-off-by: Hans Verkuil --- arch/arm/boot/dts/omap4-panda-a4.dts | 2 +- arch/arm/boot/dts/omap4-panda-es.dts | 2 +- arch/arm/boot/dts/omap4.dtsi | 5 +- drivers/gpu/drm/omapdrm/dss/Kconfig| 8 + drivers/gpu/drm/omapdrm/dss/Makefile | 3 + drivers/gpu/drm/omapdrm/dss/hdmi.h | 62 ++- drivers/gpu/drm/omapdrm/dss/hdmi4.c| 39 +++- drivers/gpu/drm/omapdrm/dss/hdmi_cec.c | 329 + 8 files changed, 441 insertions(+), 9 deletions(-) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi_cec.c diff --git a/arch/arm/boot/dts/omap4-panda-a4.dts b/arch/arm/boot/dts/omap4-panda-a4.dts index 78d3631..f0c1020 100644 --- a/arch/arm/boot/dts/omap4-panda-a4.dts +++ b/arch/arm/boot/dts/omap4-panda-a4.dts @@ -13,7 +13,7 @@ /* Pandaboard Rev A4+ have external pullups on SCL & SDA */ &dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)/* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts index 119f8e6..940fe4f 100644 --- a/arch/arm/boot/dts/omap4-panda-es.dts +++ b/arch/arm/boot/dts/omap4-panda-es.dts @@ -34,7 +34,7 @@ /* PandaboardES has external pullups on SCL & SDA */ &dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)/* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 2bd9c83..1bb490f 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -1006,8 +1006,9 @@ reg = <0x58006000 0x200>, <0x58006200 0x100>, <0x58006300 0x100>, - <0x58006400 0x1000>; - reg-names = "wp", "pll", "phy", "core"; + <0x58006400 0x900>, + <0x58006D00 0x100>; + reg-names = "wp", "pll", "phy", "core", "cec"; interrupts = ; status = "disabled"; ti,hwmods = "dss_hdmi"; diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig index d1fa730..69638e9 100644 --- a/drivers/gpu/drm/omapdrm/dss/Kconfig +++ b/drivers/gpu/drm/omapdrm/dss/Kconfig @@ -71,9 +71,17 @@ config OMAP4_DSS_HDMI bool "HDMI support for OMAP4" default y select OMAP2_DSS_HDMI_COMMON + select MEDIA_CEC_EDID help HDMI support for OMAP4 based SoCs. +config OMAP2_DSS_HDMI_CEC + bool "Enable HDMI CEC support for OMAP4" + depends on OMAP4_DSS_HDMI && MEDIA_CEC + default y + ---help--- + When selected the HDMI transmitter will support the CEC feature. + config OMAP5_DSS_HDMI bool "HDMI support for OMAP5" default n diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile index b651ec9..37eb597 100644 --- a/drivers/gpu/drm/omapdrm/dss/Makefile +++ b/drivers/gpu/drm/omapdrm/dss/Makefile @@ -10,6 +10,9 @@ omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o omapdss-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += hdmi_common.o hdmi_wp.o hdmi_pll.o \ hdmi_phy.o +ifeq ($(CONFIG_OMAP2_DSS_HDMI_CEC),y) + omapdss-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += hdmi_cec.o +endif omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi4_core.o omapdss-$(CONFIG_OMAP5_DSS_HDMI) += hdmi5.o hdmi5_core.o ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h index 53616b0..7cf8a91 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "dss.h" @@ -83,6 +84,31 @@ #define HDMI_TXPHY_PAD_CFG_CTRL0xC #define HDMI_TXPHY_BIST_CONTROL0x1C +/* HDMI CEC */
[RFC PATCH 1/3] drm/omap: fix OMAP4 hdmi_core_powerdown_disable()
From: Tomi Valkeinen hdmi_core_powerdown_disable() is supposed to disable HDMI core's power-down mode. However, the function sets the power-down bit to 0, which means "enable power-down". This hasn't caused any issues as the PD seems to affect only interrupts from HDMI core, and none of those interrupts are used at the moment. CEC functionality requires core interrupts, and the PD mode needs to be fixed. This patch fixes hdmi_core_powerdown_disable() to actually disable the PD mode. Signed-off-by: Tomi Valkeinen Reported-by: Hans Verkuil --- drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c index fa72e73..ef3afe9 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c @@ -211,7 +211,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) { DSSDBG("Enter hdmi_core_powerdown_disable\n"); - REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0); + REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x1, 0, 0); } static void hdmi_core_swreset_release(struct hdmi_core_data *core) -- 2.8.1
[RFC PATCH 3/3] encoder-tpd12s015: keep the ls_oe_gpio on while the phys_addr is valid
From: Hans Verkuil As long as there is a valid physical address in the EDID and the omap CEC support is enabled, then we keep ls_oe_gpio on to ensure the CEC signal is passed through the tpd12s015. Signed-off-by: Hans Verkuil Suggested-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 916a899..efbba23 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -65,6 +66,7 @@ static void tpd_disconnect(struct omap_dss_device *dssdev, return; gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0); + gpiod_set_value_cansleep(ddata->ls_oe_gpio, 0); dst->src = NULL; dssdev->dst = NULL; @@ -142,6 +144,7 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, { struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *in = ddata->in; + bool valid_phys_addr = 0; int r; if (!gpiod_get_value_cansleep(ddata->hpd_gpio)) @@ -151,7 +154,15 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, r = in->ops.hdmi->read_edid(in, edid, len); - gpiod_set_value_cansleep(ddata->ls_oe_gpio, 0); +#ifdef CONFIG_OMAP2_DSS_HDMI_CEC + /* +* In order to support CEC this pin should remain high +* as long as the EDID has a valid physical address. +*/ + valid_phys_addr = + cec_get_edid_phys_addr(edid, r, NULL) != CEC_PHYS_ADDR_INVALID; +#endif + gpiod_set_value_cansleep(ddata->ls_oe_gpio, valid_phys_addr); return r; } -- 2.8.1
[PATCHv16 00/13] HDMI CEC framework
From: Hans Verkuil Hi all, The sixteenth version of this patchset does some final cleanup and I'll post a pull request on the linux-media list for this patch series. At first I didn't want to post a v16 at all, but there were just a bit too many changes, even though each change itself was trivial. While the pull request will be for 4.7 I think it is more likely that it will end up in 4.8 given how late we are in the 4.7 cycle. I dropped the RFC patches for the pulse8 and ARC/CDC support since those aren't ready for mainlining. Same for the omap4 support patches I posted today. See the changelog below for more details. The cec-ctl and cec-compliance utilities used to test the CEC framework can be found here: http://git.linuxtv.org/cgit.cgi/hverkuil/v4l-utils.git/log/?h=cec Best regards, Hans Changes since v15 = - Properly document cec-edid.h - Fix various sparse/smatch warnings - Fixed several DocBook issues - Fixed incorrect return values in the adv drivers that caused an otherwise harmless WARN_ON. Changes since v14 = - Dropped the Samsung dts patches, these will go in via the samsung tree. - CEC_LOG_STATUS is replaced by a debugfs status file. - Dropped the reserved fields in the API, use versioning instead. Two flags field were added instead. - Extended cec_caps with a version field. - Dropped CEC_CAP_IS_SOURCE as it is not needed in practice. - The adv drivers now create the CEC adapter themselves instead of leaving that to the bridge. It greatly simplifies the code and it was really a left-over from the early days of the framework. - The CEC implementation of the adv drivers is now configured through a separate config option. CEC is an optional HDMI feature and you may not want to compile this in if your hardware hasn't hooked up the CEC pin. - The EDID CEC helper functions have been split off into their own cec-edid module. You likely need them even if MEDIA_CEC is not set. - Added missing copyright statements. - Added RFC code for the pulse-eight USB CEC adapter. Changes since v13 = - Removed CEC_CAP_STATE and _VENDOR_ID - Removed CEC_ADAP_G/S_STATE and CEC_ADAP_G/S_VENDOR_ID - Add vendor_id to struct cec_log_addrs - CEC_EVENT_STATE_CHANGE now reports the physical address, the logical address mask and the logical address type mask. - Add the logical address mask and the logical address type mask to struct cec_log_addrs. - Dropped cec_enable, instead enable/disable the adapter based on the physical address. - Once a valid physical address is available and userspace or driver specified the requested logical address configuration the framework will automatically claim the needed logical addresses. It will retry the last used addresses first, as per the recommendation in the CEC specification. - Dropped CEC power status handling: it's not clear if the kernel should handle that, and if it has to, whether this is the correct way. - Dropped CEC_EVENT_PHYS_ADDR_CHANGE, this is now handled by CEC_EVENT_STATE_CHANGE. - Add helper functions for manipulating physical addresses. - Updated documentation. - Dropped ninputs field in struct cec_caps. - Dropped CEC_EVENT_INPUTS_CHANGE, was never used and it is unclear if it is needed. Changes since v12 = - Added driver and name fields to the cec_caps struct. Without this it was very difficult to tell CEC adapters apart in a human readable manner. - Renamed CEC_CAP_IO to CEC_CAP_TRANSMIT, which better describes this capability. - Added the CEC_ADAP_LOG_STATUS to log the current status of the CEC adapter. Very useful when debugging. - Added comments to the cec.c source. - Added a timeout when waiting for a transmit to finish. Without the timeout the state machine could lock up when dealing with broken CEC adapter drivers or just unlucky situations. - Commenting the code also found a number of bugs which have been fixed. - Trying to poll yourself is now handled by the framework since different hardware would give different results. The framework will just NACK it. - Disabling the CEC adapter doesn't clear the physical address anymore. This turned out to be quite painful for applications. - Merged the CLAIM/RELEASE, G/S_MONITOR and G_PASSTHROUGH ioctls into two G/S_MODE ioctls. This allows you to tell the driver which initiator and follower modes you want, and greatly simplifies how these modes are handled. Changes since v11 = - Add a new CEC_EVENT_PHYS_ADDR_CHANGED to report when the physical address of the CEC adapter changes. Since the physical address is obtained from the EDID the application has to be informed when the kernel (or userspace for that matter) sets that. - Add a new internal cec_set_phys_addr() function to change the physical address and post the event. - Modified the retry-transmit mechanism: the framework will do the retry if the low-level driver retur
[PATCHv16 01/13] input.h: add BUS_CEC type
From: Hans Verkuil Inputs can come in over the HDMI CEC bus, so add a new type for this. Signed-off-by: Hans Verkuil Acked-by: Dmitry Torokhov --- include/uapi/linux/input.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index 0111384..c514941 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h @@ -247,6 +247,7 @@ struct input_mask { #define BUS_ATARI 0x1B #define BUS_SPI0x1C #define BUS_RMI0x1D +#define BUS_CEC0x1E /* * MT_TOOL types -- 2.8.1
[PATCHv16 03/13] rc: Add HDMI CEC protocol handling
From: Kamil Debski Add handling of remote control events coming from the HDMI CEC bus. This patch includes a new keymap that maps values found in the CEC messages to the keys pressed and released. Also, a new protocol has been added to the core. Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil --- drivers/media/rc/keymaps/Makefile | 1 + drivers/media/rc/keymaps/rc-cec.c | 174 ++ drivers/media/rc/rc-main.c| 1 + include/media/rc-map.h| 5 +- 4 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 drivers/media/rc/keymaps/rc-cec.c diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index fbbd3bb..9cffcc6 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-behold.o \ rc-behold-columbus.o \ rc-budget-ci-old.o \ + rc-cec.o \ rc-cinergy-1400.o \ rc-cinergy.o \ rc-delock-61959.o \ diff --git a/drivers/media/rc/keymaps/rc-cec.c b/drivers/media/rc/keymaps/rc-cec.c new file mode 100644 index 000..193cdca --- /dev/null +++ b/drivers/media/rc/keymaps/rc-cec.c @@ -0,0 +1,174 @@ +/* Keytable for the CEC remote control + * + * Copyright (c) 2015 by Kamil Debski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +/* CEC Spec "High-Definition Multimedia Interface Specification" can be obtained + * here: http://xtreamerdev.googlecode.com/files/CEC_Specs.pdf + * The list of control codes is listed in Table 27: User Control Codes p. 95 */ + +static struct rc_map_table cec[] = { + { 0x00, KEY_OK }, + { 0x01, KEY_UP }, + { 0x02, KEY_DOWN }, + { 0x03, KEY_LEFT }, + { 0x04, KEY_RIGHT }, + { 0x05, KEY_RIGHT_UP }, + { 0x06, KEY_RIGHT_DOWN }, + { 0x07, KEY_LEFT_UP }, + { 0x08, KEY_LEFT_DOWN }, + { 0x09, KEY_ROOT_MENU }, /* CEC Spec: Device Root Menu - see Note 2 */ + /* Note 2: This is the initial display that a device shows. It is +* device-dependent and can be, for example, a contents menu, setup +* menu, favorite menu or other menu. The actual menu displayed +* may also depend on the device's current state. */ + { 0x0a, KEY_SETUP }, + { 0x0b, KEY_MENU }, /* CEC Spec: Contents Menu */ + { 0x0c, KEY_FAVORITES }, /* CEC Spec: Favorite Menu */ + { 0x0d, KEY_EXIT }, + /* 0x0e-0x0f: Reserved */ + { 0x10, KEY_MEDIA_TOP_MENU }, + { 0x11, KEY_CONTEXT_MENU }, + /* 0x12-0x1c: Reserved */ + { 0x1d, KEY_DIGITS }, /* CEC Spec: select/toggle a Number Entry Mode */ + { 0x1e, KEY_NUMERIC_11 }, + { 0x1f, KEY_NUMERIC_12 }, + /* 0x20-0x29: Keys 0 to 9 */ + { 0x20, KEY_NUMERIC_0 }, + { 0x21, KEY_NUMERIC_1 }, + { 0x22, KEY_NUMERIC_2 }, + { 0x23, KEY_NUMERIC_3 }, + { 0x24, KEY_NUMERIC_4 }, + { 0x25, KEY_NUMERIC_5 }, + { 0x26, KEY_NUMERIC_6 }, + { 0x27, KEY_NUMERIC_7 }, + { 0x28, KEY_NUMERIC_8 }, + { 0x29, KEY_NUMERIC_9 }, + { 0x2a, KEY_DOT }, + { 0x2b, KEY_ENTER }, + { 0x2c, KEY_CLEAR }, + /* 0x2d-0x2e: Reserved */ + { 0x2f, KEY_NEXT_FAVORITE }, /* CEC Spec: Next Favorite */ + { 0x30, KEY_CHANNELUP }, + { 0x31, KEY_CHANNELDOWN }, + { 0x32, KEY_PREVIOUS }, /* CEC Spec: Previous Channel */ + { 0x33, KEY_SOUND }, /* CEC Spec: Sound Select */ + { 0x34, KEY_VIDEO }, /* 0x34: CEC Spec: Input Select */ + { 0x35, KEY_INFO }, /* CEC Spec: Display Information */ + { 0x36, KEY_HELP }, + { 0x37, KEY_PAGEUP }, + { 0x38, KEY_PAGEDOWN }, + /* 0x39-0x3f: Reserved */ + { 0x40, KEY_POWER }, + { 0x41, KEY_VOLUMEUP }, + { 0x42, KEY_VOLUMEDOWN }, + { 0x43, KEY_MUTE }, + { 0x44, KEY_PLAYCD }, + { 0x45, KEY_STOPCD }, + { 0x46, KEY_PAUSECD }, + { 0x47, KEY_RECORD }, + { 0x48, KEY_REWIND }, + { 0x49, KEY_FASTFORWARD }, + { 0x4a, KEY_EJECTCD }, /* CEC Spec: Eject */ + { 0x4b, KEY_FORWARD }, + { 0x4c, KEY_BACK }, + { 0x4d, KEY_STOP_RECORD }, /* CEC Spec: Stop-Record */ + { 0x4e, KEY_PAUSE_RECORD }, /* CEC Spec: Pause-Record */ + /* 0x4f: Reserved */ + { 0x50, KEY_ANGLE }, + { 0x51, KEY_TV2 }, + { 0x52, KEY_VOD }, /* CEC Spec: Video on Demand */ + { 0x53, KEY_EPG }, + { 0x54, KEY_TIME }, /* CEC Spec: Timer */ + { 0x55, KEY_CONFIG }, + /* The following codes are hard to implement at this
[PATCHv16 02/13] HID: add HDMI CEC specific keycodes
From: Kamil Debski Add HDMI CEC specific keycodes to the keycodes definition. Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil Acked-by: Dmitry Torokhov --- include/uapi/linux/input-event-codes.h | 30 ++ 1 file changed, 30 insertions(+) diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 87cf351..02b7b3a 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -611,6 +611,36 @@ #define KEY_KBDINPUTASSIST_ACCEPT 0x264 #define KEY_KBDINPUTASSIST_CANCEL 0x265 +/* Diagonal movement keys */ +#define KEY_RIGHT_UP 0x266 +#define KEY_RIGHT_DOWN 0x267 +#define KEY_LEFT_UP0x268 +#define KEY_LEFT_DOWN 0x269 + +#define KEY_ROOT_MENU 0x26a /* Show Device's Root Menu */ +#define KEY_MEDIA_TOP_MENU 0x26b /* Show Top Menu of the Media (e.g. DVD) */ +#define KEY_NUMERIC_11 0x26c +#define KEY_NUMERIC_12 0x26d +/* + * Toggle Audio Description: refers to an audio service that helps blind and + * visually impaired consumers understand the action in a program. Note: in + * some countries this is referred to as "Video Description". + */ +#define KEY_AUDIO_DESC 0x26e +#define KEY_3D_MODE0x26f +#define KEY_NEXT_FAVORITE 0x270 +#define KEY_STOP_RECORD0x271 +#define KEY_PAUSE_RECORD 0x272 +#define KEY_VOD0x273 /* Video on Demand */ +#define KEY_UNMUTE 0x274 +#define KEY_FASTREVERSE0x275 +#define KEY_SLOWREVERSE0x276 +/* + * Control a data application associated with the currently viewed channel, + * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) + */ +#define KEY_DATA 0x275 + #define BTN_TRIGGER_HAPPY 0x2c0 #define BTN_TRIGGER_HAPPY1 0x2c0 #define BTN_TRIGGER_HAPPY2 0x2c1 -- 2.8.1
[PATCHv16 04/13] cec: add HDMI CEC framework
From: Hans Verkuil The added HDMI CEC framework provides a generic kernel interface for HDMI CEC devices. Besides the cec module itself it also adds a cec-edid module that contains helper functions to find and manipulate the CEC physical address inside an EDID. Even if the CEC support itself is disabled, drivers will still need these functions. Note that the CEC framework is added to staging/media and that the cec.h and cec-funcs.h headers are not exported yet. While the kABI is mature, I would prefer to allow the uABI some more time before it is mainlined in case it needs more tweaks. Signed-off-by: Hans Verkuil [k.debski at samsung.com: Merged CEC Updates commit by Hans Verkuil] [k.debski at samsung.com: Merged Update author commit by Hans Verkuil] [k.debski at samsung.com: change kthread handling when setting logical address] [k.debski at samsung.com: code cleanup and fixes] [k.debski at samsung.com: add missing CEC commands to match spec] [k.debski at samsung.com: add RC framework support] [k.debski at samsung.com: move and edit documentation] [k.debski at samsung.com: add vendor id reporting] [k.debski at samsung.com: add possibility to clear assigned logical addresses] [k.debski at samsung.com: documentation fixes, clenaup and expansion] [k.debski at samsung.com: reorder of API structs and add reserved fields] [k.debski at samsung.com: fix handling of events and fix 32/64bit timespec problem] [k.debski at samsung.com: add sequence number handling] [k.debski at samsung.com: add passthrough mode] [k.debski at samsung.com: fix CEC defines, add missing CEC 2.0 commands] minor additions] Signed-off-by: Kamil Debski --- MAINTAINERS| 16 + drivers/media/Kconfig |3 + drivers/media/Makefile |2 + drivers/media/cec-edid.c | 139 ++ drivers/staging/media/Kconfig |2 + drivers/staging/media/Makefile |1 + drivers/staging/media/cec/Kconfig |8 + drivers/staging/media/cec/Makefile |1 + drivers/staging/media/cec/cec.c| 2481 include/linux/cec-funcs.h | 1871 +++ include/linux/cec.h| 985 ++ include/media/cec-edid.h | 103 ++ include/media/cec.h| 236 13 files changed, 5848 insertions(+) create mode 100644 drivers/media/cec-edid.c create mode 100644 drivers/staging/media/cec/Kconfig create mode 100644 drivers/staging/media/cec/Makefile create mode 100644 drivers/staging/media/cec/cec.c create mode 100644 include/linux/cec-funcs.h create mode 100644 include/linux/cec.h create mode 100644 include/media/cec-edid.h create mode 100644 include/media/cec.h diff --git a/MAINTAINERS b/MAINTAINERS index bfcb7ea..83bd865 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2760,6 +2760,22 @@ F: drivers/net/ieee802154/cc2520.c F: include/linux/spi/cc2520.h F: Documentation/devicetree/bindings/net/ieee802154/cc2520.txt +CEC DRIVER +M: Hans Verkuil +L: linux-media at vger.kernel.org +T: git git://linuxtv.org/media_tree.git +W: http://linuxtv.org +S: Supported +F: Documentation/cec.txt +F: Documentation/DocBook/media/v4l/cec* +F: drivers/staging/media/cec/cec.c +F: drivers/media/cec-edid.c +F: drivers/media/rc/keymaps/rc-cec.c +F: include/media/cec.h +F: include/media/cec-edid.h +F: include/linux/cec.h +F: include/linux/cec-funcs.h + CELL BROADBAND ENGINE ARCHITECTURE M: Arnd Bergmann L: linuxppc-dev at lists.ozlabs.org diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index a8518fb..052dcf7 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -80,6 +80,9 @@ config MEDIA_RC_SUPPORT Say Y when you have a TV or an IR device. +config MEDIA_CEC_EDID + tristate + # # Media controller # Selectable only for webcam/grabbers, as other drivers don't use it diff --git a/drivers/media/Makefile b/drivers/media/Makefile index e608bbc..b56f013 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -2,6 +2,8 @@ # Makefile for the kernel multimedia device drivers. # +obj-$(CONFIG_MEDIA_CEC_EDID) += cec-edid.o + media-objs := media-device.o media-devnode.o media-entity.o # diff --git a/drivers/media/cec-edid.c b/drivers/media/cec-edid.c new file mode 100644 index 000..50202d8 --- /dev/null +++ b/drivers/media/cec-edid.c @@ -0,0 +1,139 @@ +/* + * cec-edid - HDMI Consumer Electronics Control EDID & CEC helper functions + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED T
[PATCHv16 05/13] cec/TODO: add TODO file so we know why this is still in staging
From: Hans Verkuil Explain why cec.c is still in staging. Signed-off-by: Hans Verkuil --- drivers/staging/media/cec/TODO | 13 + 1 file changed, 13 insertions(+) create mode 100644 drivers/staging/media/cec/TODO diff --git a/drivers/staging/media/cec/TODO b/drivers/staging/media/cec/TODO new file mode 100644 index 000..c0751ef --- /dev/null +++ b/drivers/staging/media/cec/TODO @@ -0,0 +1,13 @@ +The reason why cec.c is still in staging is that I would like +to have a bit more confidence in the uABI. The kABI is fine, +no problem there, but I would like to let the public API mature +a bit. + +Once I'm confident that I didn't miss anything then the cec.c source +can move to drivers/media and the linux/cec.h and linux/cec-funcs.h +headers can move to uapi/linux and added to uapi/linux/Kbuild to make +them public. + +Hopefully this will happen later in 2016. + +Hans Verkuil -- 2.8.1
[PATCHv16 06/13] cec: add compat32 ioctl support
From: Hans Verkuil The CEC ioctls didn't have compat32 support, so they returned -ENOTTY when used in a 32 bit application on a 64 bit kernel. Since all the CEC ioctls are 32-bit compatible adding support for this API is trivial. Signed-off-by: Hans Verkuil --- fs/compat_ioctl.c | 12 1 file changed, 12 insertions(+) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index bd01b92..c1e9f29 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "internal.h" @@ -1377,6 +1378,17 @@ COMPATIBLE_IOCTL(VIDEO_GET_NAVI) COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES) COMPATIBLE_IOCTL(VIDEO_GET_SIZE) COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE) +/* cec */ +COMPATIBLE_IOCTL(CEC_ADAP_G_CAPS) +COMPATIBLE_IOCTL(CEC_ADAP_G_LOG_ADDRS) +COMPATIBLE_IOCTL(CEC_ADAP_S_LOG_ADDRS) +COMPATIBLE_IOCTL(CEC_ADAP_G_PHYS_ADDR) +COMPATIBLE_IOCTL(CEC_ADAP_S_PHYS_ADDR) +COMPATIBLE_IOCTL(CEC_G_MODE) +COMPATIBLE_IOCTL(CEC_S_MODE) +COMPATIBLE_IOCTL(CEC_TRANSMIT) +COMPATIBLE_IOCTL(CEC_RECEIVE) +COMPATIBLE_IOCTL(CEC_DQEVENT) /* joystick */ COMPATIBLE_IOCTL(JSIOCGVERSION) -- 2.8.1
[PATCHv16 08/13] DocBook/media: add CEC documentation
From: Hans Verkuil Add DocBook documentation for the CEC API. Signed-off-by: Hans Verkuil [k.debski at samsung.com: add documentation for passthrough mode] [k.debski at samsung.com: minor fixes and change of reserved field sizes] Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil --- Documentation/DocBook/device-drivers.tmpl | 4 + Documentation/DocBook/media/Makefile | 2 + Documentation/DocBook/media/v4l/biblio.xml | 10 + Documentation/DocBook/media/v4l/cec-api.xml| 72 + Documentation/DocBook/media/v4l/cec-func-close.xml | 59 Documentation/DocBook/media/v4l/cec-func-ioctl.xml | 73 + Documentation/DocBook/media/v4l/cec-func-open.xml | 94 ++ Documentation/DocBook/media/v4l/cec-func-poll.xml | 89 ++ .../DocBook/media/v4l/cec-ioc-adap-g-caps.xml | 140 + .../DocBook/media/v4l/cec-ioc-adap-g-log-addrs.xml | 324 + .../DocBook/media/v4l/cec-ioc-adap-g-phys-addr.xml | 82 ++ .../DocBook/media/v4l/cec-ioc-dqevent.xml | 190 Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml | 245 .../DocBook/media/v4l/cec-ioc-receive.xml | 260 + Documentation/DocBook/media_api.tmpl | 6 +- 15 files changed, 1649 insertions(+), 1 deletion(-) create mode 100644 Documentation/DocBook/media/v4l/cec-api.xml create mode 100644 Documentation/DocBook/media/v4l/cec-func-close.xml create mode 100644 Documentation/DocBook/media/v4l/cec-func-ioctl.xml create mode 100644 Documentation/DocBook/media/v4l/cec-func-open.xml create mode 100644 Documentation/DocBook/media/v4l/cec-func-poll.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-adap-g-log-addrs.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-adap-g-phys-addr.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-dqevent.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-receive.xml diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index 893b2ca..31258bf 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -270,6 +270,10 @@ X!Isound/sound_firmware.c !Iinclude/media/media-devnode.h !Iinclude/media/media-entity.h + Consumer Electronics Control devices +!Iinclude/media/cec.h +!Iinclude/media/cec-edid.h + diff --git a/Documentation/DocBook/media/Makefile b/Documentation/DocBook/media/Makefile index 2840ff4..fdc1386 100644 --- a/Documentation/DocBook/media/Makefile +++ b/Documentation/DocBook/media/Makefile @@ -64,6 +64,7 @@ IOCTLS = \ $(shell perl -ne 'print "$$1 " if /\#define\s+([A-Z][^\s]+)\s+_IO/' $(srctree)/include/uapi/linux/dvb/net.h) \ $(shell perl -ne 'print "$$1 " if /\#define\s+([^\s]+)\s+_IO/' $(srctree)/include/uapi/linux/dvb/video.h) \ $(shell perl -ne 'print "$$1 " if /\#define\s+([^\s]+)\s+_IO/' $(srctree)/include/uapi/linux/media.h) \ + $(shell perl -ne 'print "$$1 " if /\#define\s+([^\s]+)\s+_IO/' $(srctree)/include/linux/cec.h) \ $(shell perl -ne 'print "$$1 " if /\#define\s+([^\s]+)\s+_IO/' $(srctree)/include/uapi/linux/v4l2-subdev.h) \ DEFINES = \ @@ -100,6 +101,7 @@ STRUCTS = \ $(shell perl -ne 'print "$$1 " if (/^struct\s+([^\s]+)\s+/ && !/_old/)' $(srctree)/include/uapi/linux/dvb/net.h) \ $(shell perl -ne 'print "$$1 " if (/^struct\s+([^\s]+)\s+/)' $(srctree)/include/uapi/linux/dvb/video.h) \ $(shell perl -ne 'print "$$1 " if /^struct\s+([^\s]+)\s+/' $(srctree)/include/uapi/linux/media.h) \ + $(shell perl -ne 'print "$$1 " if /^struct\s+([^\s]+)\s+/' $(srctree)/include/linux/cec.h) \ $(shell perl -ne 'print "$$1 " if /^struct\s+([^\s]+)\s+/' $(srctree)/include/uapi/linux/v4l2-subdev.h) \ $(shell perl -ne 'print "$$1 " if /^struct\s+([^\s]+)\s+/' $(srctree)/include/uapi/linux/v4l2-mediabus.h) diff --git a/Documentation/DocBook/media/v4l/biblio.xml b/Documentation/DocBook/media/v4l/biblio.xml index 9beb30f..87f1d24 100644 --- a/Documentation/DocBook/media/v4l/biblio.xml +++ b/Documentation/DocBook/media/v4l/biblio.xml @@ -342,6 +342,16 @@ in the frequency range from 87,5 to 108,0 MHz Specification Version 1.4a + + HDMI2 + + HDMI Licensing LLC +(http://www.hdmi.org";>http://www.hdmi.org) + + High-Definition Multimedia Interface + Specification Version 2.0 + + DP diff --git a/Documentation/DocBook/media/v4l/cec-api.xml b/Docum
[PATCHv16 07/13] cec.txt: add CEC framework documentation
From: Hans Verkuil Document the new HDMI CEC framework. Signed-off-by: Hans Verkuil [k.debski at samsung.com: add DocBook documentation by Hans Verkuil, with Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil --- Documentation/cec.txt | 267 ++ 1 file changed, 267 insertions(+) create mode 100644 Documentation/cec.txt diff --git a/Documentation/cec.txt b/Documentation/cec.txt new file mode 100644 index 000..75155fe --- /dev/null +++ b/Documentation/cec.txt @@ -0,0 +1,267 @@ +CEC Kernel Support +== + +The CEC framework provides a unified kernel interface for use with HDMI CEC +hardware. It is designed to handle a multiple types of hardware (receivers, +transmitters, USB dongles). The framework also gives the option to decide +what to do in the kernel driver and what should be handled by userspace +applications. In addition it integrates the remote control passthrough +feature into the kernel's remote control framework. + + +The CEC Protocol + + +The CEC protocol enables consumer electronic devices to communicate with each +other through the HDMI connection. The protocol uses logical addresses in the +communication. The logical address is strictly connected with the functionality +provided by the device. The TV acting as the communication hub is always +assigned address 0. The physical address is determined by the physical +connection between devices. + +The CEC framework described here is up to date with the CEC 2.0 specification. +It is documented in the HDMI 1.4 specification with the new 2.0 bits documented +in the HDMI 2.0 specification. But for most of the features the freely available +HDMI 1.3a specification is sufficient: + +http://www.microprocessor.org/HDMISpecification13a.pdf + + +The Kernel Interface + + +CEC Adapter +--- + +The struct cec_adapter represents the CEC adapter hardware. It is created by +calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): + +struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + void *priv, const char *name, u32 caps, u8 available_las, + struct device *parent); +void cec_delete_adapter(struct cec_adapter *adap); + +To create an adapter you need to pass the following information: + +ops: adapter operations which are called by the CEC framework and that you +have to implement. + +priv: will be stored in adap->priv and can be used by the adapter ops. + +name: the name of the CEC adapter. Note: this name will be copied. + +caps: capabilities of the CEC adapter. These capabilities determine the + capabilities of the hardware and which parts are to be handled + by userspace and which parts are handled by kernelspace. The + capabilities are returned by CEC_ADAP_G_CAPS. + +available_las: the number of simultaneous logical addresses that this + adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS. + +parent: the parent device. + + +To register the /dev/cecX device node and the remote control device (if +CEC_CAP_RC is set) you call: + +int cec_register_adapter(struct cec_adapter *adap); + +To unregister the devices call: + +void cec_unregister_adapter(struct cec_adapter *adap); + +Note: if cec_register_adapter() fails, then call cec_delete_adapter() to +clean up. But if cec_register_adapter() succeeded, then only call +cec_unregister_adapter() to clean up, never cec_delete_adapter(). The +unregister function will delete the adapter automatically once the last user +of that /dev/cecX device has closed its file handle. + + +Implementing the Low-Level CEC Adapter +-- + +The following low-level adapter operations have to be implemented in +your driver: + +struct cec_adap_ops { + /* Low-level callbacks */ + int (*adap_enable)(struct cec_adapter *adap, bool enable); + int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); + int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); + int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, +u32 signal_free_time, struct cec_msg *msg); + void (*adap_log_status)(struct cec_adapter *adap); + + /* High-level callbacks */ + ... +}; + +The three low-level ops deal with various aspects of controlling the CEC adapter +hardware: + + +To enable/disable the hardware: + + int (*adap_enable)(struct cec_adapter *adap, bool enable); + +This callback enables or disables the CEC hardware. Enabling the CEC hardware +means powering it up in a state where no logical addresses are claimed. This +op assumes that the physical address (adap->phys_addr) is valid when enable is +true and will not change while the CEC adapter remains enabled. The initial +state of the CEC adapter after calling cec_allocate_adapter() is disabled. + +Note that adap_enable must retu
[PATCHv16 09/13] cec: adv7604: add cec support.
From: Hans Verkuil Add CEC support to the adv7604 driver. Signed-off-by: Hans Verkuil [k.debski at samsung.com: Merged changes from CEC Updates commit by Hans Verkuil] [k.debski at samsung.com: add missing methods cec/io_write_and_or] [k.debski at samsung.com: change adv7604 to adv76xx in added functions] [hansverk at cisco.com: use _clr_set instead of _and_or] --- drivers/media/i2c/Kconfig | 9 ++ drivers/media/i2c/adv7604.c | 332 +++- 2 files changed, 305 insertions(+), 36 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 993dc50..cba1fc7 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -209,6 +209,7 @@ config VIDEO_ADV7604 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API depends on GPIOLIB || COMPILE_TEST select HDMI + select MEDIA_CEC_EDID ---help--- Support for the Analog Devices ADV7604 video decoder. @@ -218,6 +219,14 @@ config VIDEO_ADV7604 To compile this driver as a module, choose M here: the module will be called adv7604. +config VIDEO_ADV7604_CEC + bool "Enable Analog Devices ADV7604 CEC support" + depends on VIDEO_ADV7604 && MEDIA_CEC + default y + ---help--- + When selected the adv7604 will support the optional + HDMI CEC feature. + config VIDEO_ADV7842 tristate "Analog Devices ADV7842 decoder" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index beb2841..f462585 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -80,6 +81,8 @@ MODULE_LICENSE("GPL"); #define ADV76XX_OP_SWAP_CB_CR (1 << 0) +#define ADV76XX_MAX_ADDRS (3) + enum adv76xx_type { ADV7604, ADV7611, @@ -184,6 +187,12 @@ struct adv76xx_state { u16 spa_port_a[2]; struct v4l2_fract aspect_ratio; u32 rgb_quantization_range; + + struct cec_adapter *cec_adap; + u8 cec_addr[ADV76XX_MAX_ADDRS]; + u8 cec_valid_addrs; + bool cec_enabled_adap; + struct workqueue_struct *work_queues; struct delayed_work delayed_work_enable_hotplug; bool restart_stdi_once; @@ -381,7 +390,8 @@ static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val) return regmap_write(state->regmap[ADV76XX_PAGE_IO], reg, val); } -static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) +static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, + u8 val) { return io_write(sd, reg, (io_read(sd, reg) & ~mask) | val); } @@ -414,6 +424,12 @@ static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) return regmap_write(state->regmap[ADV76XX_PAGE_CEC], reg, val); } +static inline int cec_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, + u8 val) +{ + return cec_write(sd, reg, (cec_read(sd, reg) & ~mask) | val); +} + static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg) { struct adv76xx_state *state = to_state(sd); @@ -872,9 +888,9 @@ static int adv76xx_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) { struct adv76xx_state *state = to_state(sd); const struct adv76xx_chip_info *info = state->info; + u16 cable_det = info->read_cable_det(sd); - return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl, - info->read_cable_det(sd)); + return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl, cable_det); } static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, @@ -1900,6 +1916,210 @@ static int adv76xx_set_format(struct v4l2_subdev *sd, return 0; } +#if IS_ENABLED(CONFIG_VIDEO_ADV7604_CEC) +static void adv76xx_cec_tx_raw_status(struct v4l2_subdev *sd, u8 tx_raw_status) +{ + struct adv76xx_state *state = to_state(sd); + + if ((cec_read(sd, 0x11) & 0x01) == 0) { + v4l2_dbg(1, debug, sd, "%s: tx raw: tx disabled\n", __func__); + return; + } + + if (tx_raw_status & 0x02) { + v4l2_dbg(1, debug, sd, "%s: tx raw: arbitration lost\n", +__func__); + cec_transmit_done(state->cec_adap, CEC_TX_STATUS_ARB_LOST, + 1, 0, 0, 0); + } + if (tx_raw_status & 0x04) { + u8 status; + u8 nack_cnt; + u8 low_drive_cnt; + + v4l2_dbg(1, debug, sd, "%s: tx raw: retry failed\n", __func__); + /* +* We set this status bit since this
[PATCHv16 10/13] cec: adv7842: add cec support
From: Hans Verkuil Add CEC support to the adv7842 driver. Signed-off-by: Hans Verkuil --- drivers/media/i2c/Kconfig | 9 ++ drivers/media/i2c/adv7842.c | 368 2 files changed, 314 insertions(+), 63 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index cba1fc7..5168454 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -231,6 +231,7 @@ config VIDEO_ADV7842 tristate "Analog Devices ADV7842 decoder" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API select HDMI + select MEDIA_CEC_EDID ---help--- Support for the Analog Devices ADV7842 video decoder. @@ -240,6 +241,14 @@ config VIDEO_ADV7842 To compile this driver as a module, choose M here: the module will be called adv7842. +config VIDEO_ADV7842_CEC + bool "Enable Analog Devices ADV7842 CEC support" + depends on VIDEO_ADV7842 && MEDIA_CEC + default y + ---help--- + When selected the adv7842 will support the optional + HDMI CEC feature. + config VIDEO_BT819 tristate "BT819A VideoStream decoder" depends on VIDEO_V4L2 && I2C diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index ecaacb0..297ba7a 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,8 @@ MODULE_LICENSE("GPL"); #define ADV7842_OP_SWAP_CB_CR (1 << 0) +#define ADV7842_MAX_ADDRS (3) + /* ** * @@ -142,6 +145,11 @@ struct adv7842_state { struct v4l2_ctrl *free_run_color_ctrl_manual; struct v4l2_ctrl *free_run_color_ctrl; struct v4l2_ctrl *rgb_quantization_range_ctrl; + + struct cec_adapter *cec_adap; + u8 cec_addr[ADV7842_MAX_ADDRS]; + u8 cec_valid_addrs; + bool cec_enabled_adap; }; /* Unsupported timings. This device cannot support 720p30. */ @@ -418,9 +426,9 @@ static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) return adv_smbus_write_byte_data(state->i2c_cec, reg, val); } -static inline int cec_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) +static inline int cec_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) { - return cec_write(sd, reg, (cec_read(sd, reg) & mask) | val); + return cec_write(sd, reg, (cec_read(sd, reg) & ~mask) | val); } static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg) @@ -696,6 +704,18 @@ adv7842_get_dv_timings_cap(struct v4l2_subdev *sd) /* --- */ +static u16 adv7842_read_cable_det(struct v4l2_subdev *sd) +{ + u8 reg = io_read(sd, 0x6f); + u16 val = 0; + + if (reg & 0x02) + val |= 1; /* port A */ + if (reg & 0x01) + val |= 2; /* port B */ + return val; +} + static void adv7842_delayed_work_enable_hotplug(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); @@ -762,50 +782,18 @@ static int edid_write_vga_segment(struct v4l2_subdev *sd) return 0; } -static int edid_spa_location(const u8 *edid) -{ - u8 d; - - /* -* TODO, improve and update for other CEA extensions -* currently only for 1 segment (256 bytes), -* i.e. 1 extension block and CEA revision 3. -*/ - if ((edid[0x7e] != 1) || - (edid[0x80] != 0x02) || - (edid[0x81] != 0x03)) { - return -EINVAL; - } - /* -* search Vendor Specific Data Block (tag 3) -*/ - d = edid[0x82] & 0x7f; - if (d > 4) { - int i = 0x84; - int end = 0x80 + d; - do { - u8 tag = edid[i]>>5; - u8 len = edid[i] & 0x1f; - - if ((tag == 3) && (len >= 5)) - return i + 4; - i += len + 1; - } while (i < end); - } - return -EINVAL; -} - static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct adv7842_state *state = to_state(sd); - const u8 *val = state->hdmi_edid.edid; - int spa_loc = edid_spa_location(val); + const u8 *edid = state->hdmi_edid.edid; + int spa_loc; + u16 pa; int err = 0; int i; - v4l2_dbg(2, debug, sd, "%s: write EDID on port %c (spa at 0x%x)\n", - __func__, (port == ADV7842_EDID_PORT_A) ? 'A' : 'B', spa_loc); + v4l2_
[PATCHv16 11/13] cec: adv7511: add cec support.
From: Hans Verkuil Add CEC support to the adv7511 driver. Signed-off-by: Hans Verkuil [k.debski at samsung.com: Merged changes from CEC Updates commit by Hans Verkuil] Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil --- drivers/media/i2c/Kconfig | 9 + drivers/media/i2c/adv7511.c | 401 +++- include/media/i2c/adv7511.h | 6 +- 3 files changed, 403 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 5168454..6c2acb6 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -465,6 +465,7 @@ config VIDEO_ADV7511 tristate "Analog Devices ADV7511 encoder" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API select HDMI + select MEDIA_CEC_EDID ---help--- Support for the Analog Devices ADV7511 video encoder. @@ -473,6 +474,14 @@ config VIDEO_ADV7511 To compile this driver as a module, choose M here: the module will be called adv7511. +config VIDEO_ADV7511_CEC + bool "Enable Analog Devices ADV7511 CEC support" + depends on VIDEO_ADV7511 && MEDIA_CEC + default y + ---help--- + When selected the adv7511 will support the optional + HDMI CEC feature. + config VIDEO_AD9389B tristate "Analog Devices AD9389B encoder" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 39271c3..002117b 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -33,6 +33,7 @@ #include #include #include +#include static int debug; module_param(debug, int, 0644); @@ -59,6 +60,8 @@ MODULE_LICENSE("GPL v2"); #define ADV7511_MIN_PIXELCLOCK 2000 #define ADV7511_MAX_PIXELCLOCK 22500 +#define ADV7511_MAX_ADDRS (3) + /* ** * @@ -90,12 +93,20 @@ struct adv7511_state { struct v4l2_ctrl_handler hdl; int chip_revision; u8 i2c_edid_addr; - u8 i2c_cec_addr; u8 i2c_pktmem_addr; + u8 i2c_cec_addr; + + struct i2c_client *i2c_cec; + struct cec_adapter *cec_adap; + u8 cec_addr[ADV7511_MAX_ADDRS]; + u8 cec_valid_addrs; + bool cec_enabled_adap; + /* Is the adv7511 powered on? */ bool power_on; /* Did we receive hotplug and rx-sense signals? */ bool have_monitor; + bool enabled_irq; /* timings from s_dv_timings */ struct v4l2_dv_timings dv_timings; u32 fmt_code; @@ -227,7 +238,7 @@ static int adv_smbus_read_i2c_block_data(struct i2c_client *client, return ret; } -static inline void adv7511_edid_rd(struct v4l2_subdev *sd, u16 len, u8 *buf) +static void adv7511_edid_rd(struct v4l2_subdev *sd, uint16_t len, uint8_t *buf) { struct adv7511_state *state = get_adv7511_state(sd); int i; @@ -242,6 +253,34 @@ static inline void adv7511_edid_rd(struct v4l2_subdev *sd, u16 len, u8 *buf) v4l2_err(sd, "%s: i2c read error\n", __func__); } +static inline int adv7511_cec_read(struct v4l2_subdev *sd, u8 reg) +{ + struct adv7511_state *state = get_adv7511_state(sd); + + return i2c_smbus_read_byte_data(state->i2c_cec, reg); +} + +static int adv7511_cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) +{ + struct adv7511_state *state = get_adv7511_state(sd); + int ret; + int i; + + for (i = 0; i < 3; i++) { + ret = i2c_smbus_write_byte_data(state->i2c_cec, reg, val); + if (ret == 0) + return 0; + } + v4l2_err(sd, "%s: I2C Write Problem\n", __func__); + return ret; +} + +static inline int adv7511_cec_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, + u8 val) +{ + return adv7511_cec_write(sd, reg, (adv7511_cec_read(sd, reg) & mask) | val); +} + static int adv7511_pktmem_rd(struct v4l2_subdev *sd, u8 reg) { struct adv7511_state *state = get_adv7511_state(sd); @@ -425,16 +464,28 @@ static const struct v4l2_ctrl_ops adv7511_ctrl_ops = { #ifdef CONFIG_VIDEO_ADV_DEBUG static void adv7511_inv_register(struct v4l2_subdev *sd) { + struct adv7511_state *state = get_adv7511_state(sd); + v4l2_info(sd, "0x000-0x0ff: Main Map\n"); + if (state->i2c_cec) + v4l2_info(sd, "0x100-0x1ff: CEC Map\n"); } static int adv7511_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { + struct adv7511_state *state = get_adv7511_state(sd); + reg->size = 1; switch (reg->reg >> 8) { case 0: reg->val = adv7511_rd(sd, reg->reg & 0xff); break;
[PATCHv16 12/13] cec: s5p-cec: Add s5p-cec driver
From: Kamil Debski Add CEC interface driver present in the Samsung Exynos range of SoCs. The following files were based on work by SangPil Moon: - exynos_hdmi_cec.h - exynos_hdmi_cecctl.c Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil --- .../devicetree/bindings/media/s5p-cec.txt | 31 +++ MAINTAINERS| 7 + drivers/media/platform/Kconfig | 11 + drivers/media/platform/Makefile| 1 + drivers/media/platform/s5p-cec/Makefile| 2 + drivers/media/platform/s5p-cec/exynos_hdmi_cec.h | 38 +++ .../media/platform/s5p-cec/exynos_hdmi_cecctrl.c | 209 +++ drivers/media/platform/s5p-cec/regs-cec.h | 96 +++ drivers/media/platform/s5p-cec/s5p_cec.c | 295 + drivers/media/platform/s5p-cec/s5p_cec.h | 76 ++ 10 files changed, 766 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/s5p-cec.txt create mode 100644 drivers/media/platform/s5p-cec/Makefile create mode 100644 drivers/media/platform/s5p-cec/exynos_hdmi_cec.h create mode 100644 drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c create mode 100644 drivers/media/platform/s5p-cec/regs-cec.h create mode 100644 drivers/media/platform/s5p-cec/s5p_cec.c create mode 100644 drivers/media/platform/s5p-cec/s5p_cec.h diff --git a/Documentation/devicetree/bindings/media/s5p-cec.txt b/Documentation/devicetree/bindings/media/s5p-cec.txt new file mode 100644 index 000..925ab4d --- /dev/null +++ b/Documentation/devicetree/bindings/media/s5p-cec.txt @@ -0,0 +1,31 @@ +* Samsung HDMI CEC driver + +The HDMI CEC module is present is Samsung SoCs and its purpose is to +handle communication between HDMI connected devices over the CEC bus. + +Required properties: + - compatible : value should be following + "samsung,s5p-cec" + + - reg : Physical base address of the IP registers and length of memory + mapped region. + + - interrupts : HDMI CEC interrupt number to the CPU. + - clocks : from common clock binding: handle to HDMI CEC clock. + - clock-names : from common clock binding: must contain "hdmicec", + corresponding to entry in the clocks property. + - samsung,syscon-phandle - phandle to the PMU system controller + +Example: + +hdmicec: cec at 100B { + compatible = "samsung,s5p-cec"; + reg = <0x100B 0x200>; + interrupts = <0 114 0>; + clocks = <&clock CLK_HDMI_CEC>; + clock-names = "hdmicec"; + samsung,syscon-phandle = <&pmu_system_controller>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_cec>; + status = "okay"; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 83bd865..0e43b30 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1581,6 +1581,13 @@ L: linux-media at vger.kernel.org S: Maintained F: drivers/media/platform/s5p-tv/ +ARM/SAMSUNG S5P SERIES HDMI CEC SUBSYSTEM SUPPORT +M: Kyungmin Park +L: linux-arm-kernel at lists.infradead.org +L: linux-media at vger.kernel.org +S: Maintained +F: drivers/media/platform/s5p-cec/ + ARM/SAMSUNG S5P SERIES JPEG CODEC SUPPORT M: Andrzej Pietrasiewicz M: Jacek Anaszewski diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 84e041c..c3945c3 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -108,6 +108,17 @@ config VIDEO_S3C_CAMIF source "drivers/media/platform/soc_camera/Kconfig" source "drivers/media/platform/exynos4-is/Kconfig" source "drivers/media/platform/s5p-tv/Kconfig" + +config VIDEO_SAMSUNG_S5P_CEC + tristate "Samsung S5P CEC driver" + depends on VIDEO_DEV && MEDIA_CEC && (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST) + default n + ---help--- + This is a driver for Samsung S5P HDMI CEC interface. It uses the + generic CEC framework interface. + CEC bus is present in the HDMI connector and enables communication + between compatible devices. + source "drivers/media/platform/am437x/Kconfig" source "drivers/media/platform/xilinx/Kconfig" diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index bbb7bd1..f598c80 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE) += m2m-deinterlace.o obj-$(CONFIG_VIDEO_S3C_CAMIF) += s3c-camif/ obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS) += exynos4-is/ +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC)+= s5p-cec/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC)+= s5p-mfc/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/ diff --git a/drivers/media/platform/s5p-ce
[PATCHv16 13/13] vivid: add CEC emulation
From: Hans Verkuil The vivid driver has been extended to provide CEC adapters for the HDMI input and HDMI outputs in order to test CEC applications. This CEC emulation is faithful to the CEC timings (i.e., it all at a snail's pace). Signed-off-by: Hans Verkuil --- Documentation/video4linux/vivid.txt | 36 +++- drivers/media/platform/vivid/Kconfig | 9 + drivers/media/platform/vivid/Makefile| 4 + drivers/media/platform/vivid/vivid-cec.c | 254 +++ drivers/media/platform/vivid/vivid-cec.h | 33 +++ drivers/media/platform/vivid/vivid-core.c| 119 ++- drivers/media/platform/vivid/vivid-core.h| 27 +++ drivers/media/platform/vivid/vivid-kthread-cap.c | 11 + drivers/media/platform/vivid/vivid-vid-cap.c | 23 +- drivers/media/platform/vivid/vivid-vid-common.c | 7 + 10 files changed, 508 insertions(+), 15 deletions(-) create mode 100644 drivers/media/platform/vivid/vivid-cec.c create mode 100644 drivers/media/platform/vivid/vivid-cec.h diff --git a/Documentation/video4linux/vivid.txt b/Documentation/video4linux/vivid.txt index 8da5d2a..1b26519 100644 --- a/Documentation/video4linux/vivid.txt +++ b/Documentation/video4linux/vivid.txt @@ -74,7 +74,8 @@ Section 11: Cropping, Composing, Scaling Section 12: Formats Section 13: Capture Overlay Section 14: Output Overlay -Section 15: Some Future Improvements +Section 15: CEC (Consumer Electronics Control) +Section 16: Some Future Improvements Section 1: Configuring the driver @@ -364,7 +365,11 @@ For HDMI inputs it is possible to set the EDID. By default a simple EDID is provided. You can only set the EDID for HDMI inputs. Internally, however, the EDID is shared between all HDMI inputs. -No interpretation is done of the EDID data. +No interpretation is done of the EDID data with the exception of the +physical address. See the CEC section for more details. + +There is a maximum of 15 HDMI inputs (if there are more, then they will be +reduced to 15) since that's the limitation of the EDID physical address. Section 3: Video Output @@ -409,6 +414,9 @@ standard, and for all others a 1:1 pixel aspect ratio is returned. An HDMI output has a valid EDID which can be obtained through VIDIOC_G_EDID. +There is a maximum of 15 HDMI outputs (if there are more, then they will be +reduced to 15) since that's the limitation of the EDID physical address. See +also the CEC section for more details. Section 4: VBI Capture -- @@ -1108,7 +1116,26 @@ capabilities will slow down the video loop considerably as a lot of checks have to be done per pixel. -Section 15: Some Future Improvements +Section 15: CEC (Consumer Electronics Control) +-- + +If there are HDMI inputs then a CEC adapter will be created that has +the same number of input ports. This is the equivalent of e.g. a TV that +has that number of inputs. Each HDMI output will also create a +CEC adapter that is hooked up to the corresponding input port, or (if there +are more outputs than inputs) is not hooked up at all. In other words, +this is the equivalent of hooking up each output device to an input port of +the TV. Any remaining output devices remain unconnected. + +The EDID that each output reads reports a unique CEC physical address that is +based on the physical address of the EDID of the input. So if the EDID of the +receiver has physical address A.B.0.0, then each output will see an EDID +containing physical address A.B.C.0 where C is 1 to the number of inputs. If +there are more outputs than inputs then the remaining outputs have a CEC adapter +that is disabled and reports an invalid physical address. + + +Section 16: Some Future Improvements Just as a reminder and in no particular order: @@ -1121,8 +1148,6 @@ Just as a reminder and in no particular order: - Fix sequence/field numbering when looping of video with alternate fields - Add support for V4L2_CID_BG_COLOR for video outputs - Add ARGB888 overlay support: better testing of the alpha channel -- Add custom DV timings support -- Add support for V4L2_DV_FL_REDUCED_FPS - Improve pixel aspect support in the tpg code by passing a real v4l2_fract - Use per-queue locks and/or per-device locks to improve throughput - Add support to loop from a specific output to a specific input across @@ -1133,3 +1158,4 @@ Just as a reminder and in no particular order: - Make a thread for the RDS generation, that would help in particular for the "Controls" RDS Rx I/O Mode as the read-only RDS controls could be updated in real-time. +- Changing the EDID should cause hotplug detect emulation to happen. diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig index f535f57..20c5eea 100644 --- a/drivers/media/platform/vivid/Kconfig +++ b/drivers/media/platform/vivid/Kconf
omap4: how to get the HDMI core IRQ?
Hi Tomi, On 03/30/2016 03:37 AM, Tomi Valkeinen wrote: > Hi Hans, > > On 24/03/16 23:20, Hans Verkuil wrote: >> Hi Tomi, >> >> I hope you (or someone else on this list) can help me find the problem in >> this code. >> >> I am working on a kernel framework for HDMI CEC (see >> https://lwn.net/Articles/680942/). >> In order to get as much experience with different devices as possible I am >> trying to >> implement it on my omap4430 Pandaboard. The big problem I am facing is that >> the CEC >> interrupts come in through the HDMI_IRQ_CORE interrupt, and that just >> refuses to >> trigger. >> >> The code below adds support for this core interrupt and it is supposed to >> trigger it >> using the Software Induced interrupt to keep the code as simple as possible. > > So this irq is just for testing? Yes, that was the easiest way to check the core irq without requiring lots of other changes. >> On boot I get this debug line from the pr_info in my code: >> >> irqstat 0200 wp_irq 0601 raw 2001 intr_state 0001 intr1 >> 0080 unmask1 0080 intr_ctrl 000a >> >> As far as I can see everything looks perfectly fine, except for the fact >> that bit 0 >> of the irqstat is stubbornly 0. >> >> This is using kernel 4.5 with only this patch applied. >> >> What am I missing? > > Set SYS_CTRL1:PD to 1 (I presume you have the NDA HDMI TRM?). Yes, I have it. > Apparently we set it always to 0 in > hdmi4_core.c:hdmi_core_powerdown_disable(), but never enable it. I guess > it only affects core irqs, so there have been no side effects. > > But it would make sense to either have a matching call in the enable > path, or then just set it to 0 when initializing the IP. I think it should be set in hdmi_core_video_config(). It sets other SYS_CTRL1 bits there as well, and that is probably why I missed it. I just never realized that the PD bit wasn't set there. Thank you very much! I'm abroad right now, but once I'm back I'll test this first thing. > >> >> The reward for the right answer will be HDMI CEC support for omap4 (and any >> other TI device >> with the same CEC IP). > > Ok. When is it ready? ;) Once I get the irq working the omap4 support should be ready very quickly, getting the CEC framework merged takes a bit longer, but I am aiming for kernel 4.7 pending some final tests. I'm cross-posting the patch series to dri-devel, so with luck when I post v15 it will have an omap4 driver as well. Regards, Hans
[PATCH RFC 4/5] drm/bridge: add dw-hdmi cec driver using Hans Verkil's CEC code
On 08/12/2016 04:15 PM, Russell King wrote: > Add a CEC driver for the dw-hdmi hardware using Hans Verkil's CEC That's Verkuil :-) BTW, since cec is part of the media subsystem please include linux-media for the next round. Regards, Hans
[PATCH RFC 5/5] drm/i2c: add tda998x/tda9950 CEC driver
On 08/12/2016 04:15 PM, Russell King wrote: > Add a CEC driver for the TDA9950, which is a stand-alone I2C CEC device. > The TDA9950 contains a command processor which handles retransmissions > and the low level bus protocol. The driver just has to read and write > the messages, and handle error conditions. > > Signed-off-by: Russell King > --- > drivers/gpu/drm/i2c/Kconfig | 5 + > drivers/gpu/drm/i2c/Makefile | 1 + > drivers/gpu/drm/i2c/tda9950.c | 514 > ++ > include/linux/platform_data/tda9950.h | 15 + > 4 files changed, 535 insertions(+) > create mode 100644 drivers/gpu/drm/i2c/tda9950.c > create mode 100644 include/linux/platform_data/tda9950.h > > +static int tda9950_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) > +{ > + struct tda9950_priv *priv = adap->priv; > + u16 addresses; > + u8 buf[2]; > + > + if (addr == CEC_LOG_ADDR_INVALID) > + addresses = priv->addresses = BIT(15); I saw this in patch 4/5 as well: why set bit 15? I would expect that this is just set to 0. And priv->addresses doesn't seem to be used anywhere. > + else > + addresses = priv->addresses |= BIT(addr); > + > + /* TDA9950 doesn't want address 15 set */ > + addr &= 0x7fff; > + buf[0] = addresses >> 8; > + buf[1] = addresses; > + > + return tda9950_write_range(priv->client, REG_ACKH, buf, 2); > +} > + > +static int tda9950_cec_adap_enable(struct cec_adapter *adap, bool enable) > +{ > + struct tda9950_priv *priv = adap->priv; > + > + if (!enable) { > + tda9950_release(priv); > + return 0; > + } else { Nitpick: no need for 'else' here since the 'if' always returns. > + return tda9950_open(priv); > + } > +} Regards, Hans
[PATCH RFC 1/5] video: add HDMI state notifier support
On 08/12/2016 04:14 PM, Russell King wrote: > Add support for HDMI hotplug and EDID notifiers, which is used to convey > information from HDMI drivers to their CEC and audio counterparts. > > Acked-by: Philipp Zabel I still don't really like the void *, but not enough to block this, so: Acked-by: Hans Verkuil Regards, Hans > Signed-off-by: Russell King > --- > drivers/video/Kconfig | 3 +++ > drivers/video/Makefile| 1 + > drivers/video/hdmi-notifier.c | 61 > +++ > include/linux/hdmi-notifier.h | 44 +++ > 4 files changed, 109 insertions(+) > create mode 100644 drivers/video/hdmi-notifier.c > create mode 100644 include/linux/hdmi-notifier.h > > diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig > index 3c20af999893..1ee7b9f9bb25 100644 > --- a/drivers/video/Kconfig > +++ b/drivers/video/Kconfig > @@ -36,6 +36,9 @@ config VIDEOMODE_HELPERS > config HDMI > bool > > +config HDMI_NOTIFIERS > + bool > + > if VT > source "drivers/video/console/Kconfig" > endif > diff --git a/drivers/video/Makefile b/drivers/video/Makefile > index 9ad3c17d6456..65f564906fb4 100644 > --- a/drivers/video/Makefile > +++ b/drivers/video/Makefile > @@ -1,5 +1,6 @@ > obj-$(CONFIG_VGASTATE)+= vgastate.o > obj-$(CONFIG_HDMI)+= hdmi.o > +obj-$(CONFIG_HDMI_NOTIFIERS) += hdmi-notifier.o > > obj-$(CONFIG_VT) += console/ > obj-$(CONFIG_LOGO) += logo/ > diff --git a/drivers/video/hdmi-notifier.c b/drivers/video/hdmi-notifier.c > new file mode 100644 > index ..f3b16552b0fe > --- /dev/null > +++ b/drivers/video/hdmi-notifier.c > @@ -0,0 +1,61 @@ > +#include > +#include > +#include > +#include > + > +static BLOCKING_NOTIFIER_HEAD(hdmi_notifier); > + > +int hdmi_register_notifier(struct notifier_block *nb) > +{ > + return blocking_notifier_chain_register(&hdmi_notifier, nb); > +} > +EXPORT_SYMBOL_GPL(hdmi_register_notifier); > + > +int hdmi_unregister_notifier(struct notifier_block *nb) > +{ > + return blocking_notifier_chain_unregister(&hdmi_notifier, nb); > +} > +EXPORT_SYMBOL_GPL(hdmi_unregister_notifier); > + > +void hdmi_event_connect(struct device *dev) > +{ > + struct hdmi_event_base base; > + > + base.source = dev; > + > + blocking_notifier_call_chain(&hdmi_notifier, HDMI_CONNECTED, &base); > +} > +EXPORT_SYMBOL_GPL(hdmi_event_connect); > + > +void hdmi_event_disconnect(struct device *dev) > +{ > + struct hdmi_event_base base; > + > + base.source = dev; > + > + blocking_notifier_call_chain(&hdmi_notifier, HDMI_DISCONNECTED, &base); > +} > +EXPORT_SYMBOL_GPL(hdmi_event_disconnect); > + > +void hdmi_event_new_edid(struct device *dev, const void *edid, size_t size) > +{ > + struct hdmi_event_new_edid new_edid; > + > + new_edid.base.source = dev; > + new_edid.edid = edid; > + new_edid.size = size; > + > + blocking_notifier_call_chain(&hdmi_notifier, HDMI_NEW_EDID, &new_edid); > +} > +EXPORT_SYMBOL_GPL(hdmi_event_new_edid); > + > +void hdmi_event_new_eld(struct device *dev, const u8 eld[128]) > +{ > + struct hdmi_event_new_eld new_eld; > + > + new_eld.base.source = dev; > + memcpy(new_eld.eld, eld, sizeof(new_eld.eld)); > + > + blocking_notifier_call_chain(&hdmi_notifier, HDMI_NEW_ELD, &new_eld); > +} > +EXPORT_SYMBOL_GPL(hdmi_event_new_eld); > diff --git a/include/linux/hdmi-notifier.h b/include/linux/hdmi-notifier.h > new file mode 100644 > index ..5fb710e5d68a > --- /dev/null > +++ b/include/linux/hdmi-notifier.h > @@ -0,0 +1,44 @@ > +#ifndef LINUX_HDMI_NOTIFIER_H > +#define LINUX_HDMI_NOTIFIER_H > + > +#include > + > +enum { > + HDMI_CONNECTED, > + HDMI_DISCONNECTED, > + HDMI_NEW_EDID, > + HDMI_NEW_ELD, > +}; > + > +struct hdmi_event_base { > + struct device *source; > +}; > + > +struct hdmi_event_new_edid { > + struct hdmi_event_base base; > + const void *edid; > + size_t size; > +}; > + > +struct hdmi_event_new_eld { > + struct hdmi_event_base base; > + unsigned char eld[128]; > +}; > + > +union hdmi_event { > + struct hdmi_event_base base; > + struct hdmi_event_new_edid edid; > + struct hdmi_event_new_eld eld; > +}; > + > +struct notifier_block; > + > +int hdmi_register_notifier(struct notifier_block *nb); > +int hdmi_unregister_notifier(struct notifier_block *nb); > + > +void hdmi_event_connect(struct device *dev); > +void hdmi_event_disconnect(struct device *dev); > +void hdmi_event_new_edid(struct device *dev, const void *edid, size_t size); > +void hdmi_event_new_eld(struct device *dev, const u8 eld[128]); > + > +#endif >
[PATCH RFC 5/5] drm/i2c: add tda998x/tda9950 CEC driver
On 08/12/2016 05:29 PM, Russell King - ARM Linux wrote: > On Fri, Aug 12, 2016 at 05:16:41PM +0200, Hans Verkuil wrote: >> On 08/12/2016 04:38 PM, Hans Verkuil wrote: >>> On 08/12/2016 04:15 PM, Russell King wrote: >>>> Add a CEC driver for the TDA9950, which is a stand-alone I2C CEC device. >>>> The TDA9950 contains a command processor which handles retransmissions >>>> and the low level bus protocol. The driver just has to read and write >>>> the messages, and handle error conditions. >>>> >>>> Signed-off-by: Russell King >>>> --- >>>> drivers/gpu/drm/i2c/Kconfig | 5 + >>>> drivers/gpu/drm/i2c/Makefile | 1 + >>>> drivers/gpu/drm/i2c/tda9950.c | 514 >>>> ++ >>>> include/linux/platform_data/tda9950.h | 15 + >>>> 4 files changed, 535 insertions(+) >>>> create mode 100644 drivers/gpu/drm/i2c/tda9950.c >>>> create mode 100644 include/linux/platform_data/tda9950.h >>>> >>> >>> >>> >>>> +static int tda9950_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) >>>> +{ >>>> +struct tda9950_priv *priv = adap->priv; >>>> +u16 addresses; >>>> +u8 buf[2]; >>>> + >>>> +if (addr == CEC_LOG_ADDR_INVALID) >>>> +addresses = priv->addresses = BIT(15); >>> >>> I saw this in patch 4/5 as well: why set bit 15? I would expect that this >>> is just set to 0. And priv->addresses doesn't seem to be used anywhere. >> >> Yeah, you are right, priv->addresses is used. I've been reviewing too many >> patches today. >> >> The whole BIT(15) part remains weird. If log_addr is called with >> LOG_ADDR_INVALID as argument, then the intention is that no more >> messages are to be received (unless the hardware is in snooping mode). >> So there is no need to receive broadcast messages either. > > What about hardware where you can't stop it receiving broadcast > addresses? Should drivers manually check for this in their > interrupt handler? > >> That said, I now realize that if userspace wants to configure the CEC >> device as 'Unregistered', then adap_log_addr is never called, which >> would be required if the hardware has to enable support to receive >> broadcast messages. > > I don't see how that could possibly work. The CEC specification > requires that we receive broadcast addressed messages so that (eg) > the current source can be tracked. Being present on the bus, and > participating as an active source requires the reception of > broadcast messages so that you know when you stop being an active > source. > > Nothing (afaics) enables broadcast address reception in the kernel > side, nor using cec-ctl in userspace. There are three possible 'states' of a CEC adapter w.r.t. logical addresses: 1) There is no physical address or no logical addresses have been set by the application (CEC_ADAP_S_LOG_ADDRS): in that case the device will not participate on the bus, it doesn't care about receiving messages let alone replying to them. The only exception is if the device can snoop messages, that is allowed even if CEC_ADAP_S_LOG_ADDRS is never called. That is ideal to have a 'neutral' observer of the bus that just listens but never participates. Not all hardware supports snooping, though. 2) CEC_ADAP_S_LOG_ADDRS is called and the device becomes an 'Unregistered' device (i.e. it gets logical address 15). In that case it should receive broadcast messages and be able to transmit messages. 3) CEC_ADAP_S_LOG_ADDRS is called and the device claims one or more logical addresses in the range 0-14. Then it can receive broadcast and directed messages, and of course transmit messages. From the point of view of the hardware state 1 is selected if adap_log_addr is called with LOG_ADDR_INVALID. Some hardware might still receive broadcast messages (because they can't turn that off) and those should be filtered out by the CEC framework. But I think that doesn't happen, which would be a bug. I'll verify that tomorrow. State 2 is a problem for hardware that has to enable support to receive broadcast messages since adap_log_addr is never called with LOG_ADDR_UNREGISTERED as argument. I missed that, since the hardware I tested with always accepts broadcast messages. I'll look into this tomorrow as well. It should be easy to fix. State 3 works OK. So for the dw-hdmi cec driver that means that for state 1 you set 'addresses' to 0, for state 2 you set it to BIT(15) and for state 3 you always OR wit
[PATCH RFC 5/5] drm/i2c: add tda998x/tda9950 CEC driver
On 08/12/2016 04:38 PM, Hans Verkuil wrote: > On 08/12/2016 04:15 PM, Russell King wrote: >> Add a CEC driver for the TDA9950, which is a stand-alone I2C CEC device. >> The TDA9950 contains a command processor which handles retransmissions >> and the low level bus protocol. The driver just has to read and write >> the messages, and handle error conditions. >> >> Signed-off-by: Russell King >> --- >> drivers/gpu/drm/i2c/Kconfig | 5 + >> drivers/gpu/drm/i2c/Makefile | 1 + >> drivers/gpu/drm/i2c/tda9950.c | 514 >> ++ >> include/linux/platform_data/tda9950.h | 15 + >> 4 files changed, 535 insertions(+) >> create mode 100644 drivers/gpu/drm/i2c/tda9950.c >> create mode 100644 include/linux/platform_data/tda9950.h >> > > > >> +static int tda9950_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) >> +{ >> +struct tda9950_priv *priv = adap->priv; >> +u16 addresses; >> +u8 buf[2]; >> + >> +if (addr == CEC_LOG_ADDR_INVALID) >> +addresses = priv->addresses = BIT(15); > > I saw this in patch 4/5 as well: why set bit 15? I would expect that this > is just set to 0. And priv->addresses doesn't seem to be used anywhere. Yeah, you are right, priv->addresses is used. I've been reviewing too many patches today. The whole BIT(15) part remains weird. If log_addr is called with LOG_ADDR_INVALID as argument, then the intention is that no more messages are to be received (unless the hardware is in snooping mode). So there is no need to receive broadcast messages either. That said, I now realize that if userspace wants to configure the CEC device as 'Unregistered', then adap_log_addr is never called, which would be required if the hardware has to enable support to receive broadcast messages. In addition cec_received_msg should ignore received messages if log_addr_mask of struct cec_log_addrs is 0. I think it will just pass on messages right now, and that's not right. I will look at this tomorrow when my brain isn't fried and do some more testing with 'Unregistered' scenarios. > >> +else >> +addresses = priv->addresses |= BIT(addr); >> + >> +/* TDA9950 doesn't want address 15 set */ >> +addr &= 0x7fff; Shouldn't this be 'addresses' instead of 'addr'? 'addr' makes no sense here. And if so, then I still don't understand setting BIT(15), since that bit is removed by the &=. >> +buf[0] = addresses >> 8; >> +buf[1] = addresses; >> + >> +return tda9950_write_range(priv->client, REG_ACKH, buf, 2); >> +} >> + Regards, Hans
[ANN] HDMI CEC: added cec-compliance/cec-follower utilities
Two new CEC utilities have been added to the v4l-utils repository: https://git.linuxtv.org/v4l-utils.git/ The cec-follower utility can emulate a CEC device, implementing the follower functionality needed. The cec-compliance utility can test a remote CEC device and check how compliant it is against the CEC specification. A major problem with CEC implementations is that they often poorly adhere to the standard. These two utilities are an attempt to provide a way to test CEC implementations. Many thanks go to Johan Fjeldtvedt for working on this as part of his Cisco Summer internship! The linux-media mailinglist is the main point of contact, and patches improving these utilities are welcome. Note that these CEC features have currently limited coverage: One Touch Record Deck Control Device Menu Control Audio Rate Control Tuner Control Timer Programming Capability Discovery and Control Vendor Specific Commands There is also no or very limited support for Unregistered devices, CEC switches and CDC-only devices. The compliance tests are based on CEC 2.0, although some tests are slightly different for CEC 1.4 devices. If you want to experiment with these utilities, then the easiest method is to use the vivid driver from kernel 4.8. That driver provides two emulated CEC devices. modprobe vivid This creates two cec devices: cec0 is that of the HDMI receiver, cec1 is the device for the HDMI transmitter. This can be verified with 'cec-ctl -d0' and 'cec-ctl -d1'. The physical address of the receiver is reported as 0.0.0.0, that of the transmitter as 1.0.0.0. Note: -dX is short-hand for -d /dev/cecX. The next step is to configure these two devices: cec-ctl -d0 --tv cec-ctl -d1 --playback This configures the receiver as a TV and the transmitter as a playback device. Now start cec-follower to emulate the playback device: cec-follower -d1 And start the compliance test to test the follower implementation: cec-compliance -d0 -r4 The -r4 option says that it should test the remote CEC device with logical address 4 (i.e. the playback device). These utilities require that the cec device is configured (e.g. the CEC_S_LOG_ADDRS ioctl was called), otherwise they will refuse to run. That's why cec-ctl is needed to configure the two vivid cec devices. Some tests require interactive mode. Add the -i option to enable that. Especially tests relating to Standby mode need a human to look at the TV to verify it is really in standby or not. Below is the full output for the compliance run from the example above. Sadly, it is very unlikely you'll see 0 failures with real CEC implementations. Regards, Hans Example of a compliance run: $ cec-compliance -r4 Driver Info: Driver Name: vivid Adapter Name : vivid-000-vid-cap0 Capabilities : 0x003e Logical Addresses Transmit Passthrough Remote Control Support Monitor All Driver version : 4.8.0 Available Logical Addresses: 1 Physical Address : 0.0.0.0 Logical Address Mask : 0x0001 CEC Version: 2.0 Vendor ID : 0x000c03 Logical Addresses : 1 Logical Address : 0 Primary Device Type: TV Logical Address Type : TV All Device Types : TV RC TV Profile : None Device Features: None Compliance test for device /dev/cec0: The test results mean the following: OK Supported correctly by the device. OK (Not Supported) Not supported and not mandatory for the device. OK (Presumed) Presumably supported. Manually check to confirm. OK (Unexpected) Supported correctly but is not expected to be supported for this device. OK (Refused)Supported by the device, but was refused. FAILFailed and was expected to be supported by this device. Find remote devices: Polling: OK Network topology: System Information for device 4 (Playback Device 1) from device 0 (TV): CEC Version: 2.0 Physical Address : 1.0.0.0 Primary Device Type: Playback Vendor ID : 0x000c03 OSD Name : 'Playback' Power Status : On testing CEC local LA 0 (TV) to remote LA 4 (Playback Device 1): Core: Feature aborts unknown messages: OK Feature aborts Abort message: OK Give Device Power Status feature: Give Device Power Status: OK Report Device Power Status: OK (Presumed) System Info
[PATCH for v4.8] cec-edid: check for IEEE identifier
The cec_get_edid_spa_location() function did not verify that the IEEE identifier in the Vendor Specific Data Block matched the HDMI-LLC identifier. This could result in the wrong VSDB block being returned. For example, for HDMI 2.0 EDIDs there is also a HDMI Forum VSDB. So check the IEEE identifier as well. Signed-off-by: Hans Verkuil --- diff --git a/drivers/media/cec-edid.c b/drivers/media/cec-edid.c index 7001824..5719b99 100644 --- a/drivers/media/cec-edid.c +++ b/drivers/media/cec-edid.c @@ -70,7 +70,10 @@ static unsigned int cec_get_edid_spa_location(const u8 *edid, unsigned int size) u8 tag = edid[i] >> 5; u8 len = edid[i] & 0x1f; - if (tag == 3 && len >= 5 && i + len <= end) + if (tag == 3 && len >= 5 && i + len <= end && + edid[i + 1] == 0x03 && + edid[i + 2] == 0x0c && + edid[i + 3] == 0x00) return i + 4; i += len + 1; } while (i < end);
[PATCH RFC 4/5] drm/bridge: add dw-hdmi cec driver using Hans Verkil's CEC code
Hi Russell, On 08/12/2016 04:15 PM, Russell King wrote: > Add a CEC driver for the dw-hdmi hardware using Hans Verkil's CEC > implementation. > > Signed-off-by: Russell King > --- > drivers/gpu/drm/bridge/Kconfig| 7 + > drivers/gpu/drm/bridge/Makefile | 1 + > drivers/gpu/drm/bridge/dw-hdmi-cec.c | 344 > ++ > drivers/gpu/drm/bridge/dw-hdmi.c | 64 +- > include/linux/platform_data/dw_hdmi-cec.h | 16 ++ > 5 files changed, 421 insertions(+), 11 deletions(-) > create mode 100644 drivers/gpu/drm/bridge/dw-hdmi-cec.c > create mode 100644 include/linux/platform_data/dw_hdmi-cec.h > > +static unsigned int parse_hdmi_addr(const struct edid *edid) > +{ > + if (!edid || edid->extensions == 0) > + return (u16)~0; > + > + return cec_get_edid_phys_addr((u8 *)edid, > + EDID_LENGTH * (edid->extensions + 1), NULL); > +} > + > +static int dw_hdmi_cec_notify(struct notifier_block *nb, unsigned long event, > + void *data) > +{ > + struct dw_hdmi_cec *cec = container_of(nb, struct dw_hdmi_cec, nb); > + union hdmi_event *event_block = data; > + unsigned int phys; > + > + dev_info(event_block->base.source, "event %lu\n", event); > + > + if (event_block->base.source != cec->adap->devnode.parent) > + return NOTIFY_OK; > + > + switch (event) { > + case HDMI_CONNECTED: > + break; > + > + case HDMI_DISCONNECTED: > + cec_s_phys_addr(cec->adap, CEC_PHYS_ADDR_INVALID, false); > + break; > + > + case HDMI_NEW_EDID: > + phys = parse_hdmi_addr(event_block->edid.edid); > + cec_s_phys_addr(cec->adap, phys, false); > + break; > + } > + > + return NOTIFY_OK; > +} Wouldn't it make a lot of sense to integrate this into the cec framework? All you need is to pass an hdmi_notifier_dev as argument to cec_allocate_adapter() and you can integrate this. If you are OK with that, then I can make patches for that. Regards, Hans
[PATCH RFC 4/5] drm/bridge: add dw-hdmi cec driver using Hans Verkil's CEC code
Hi Russell, On 08/12/16 16:15, Russell King wrote: > + ret = devm_request_threaded_irq(&pdev->dev, cec->irq, > + dw_hdmi_cec_hardirq, > + dw_hdmi_cec_thread, IRQF_SHARED, > + DEV_NAME, cec->adap); > + if (ret < 0) > + return ret; > + > + ret = cec_register_adapter(cec->adap); > + if (ret < 0) > + return ret; > + > + /* > + * CEC documentation says we must not call cec_delete_adapter > + * after a successful call to cec_register_adapter(). > + */ > + devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec); > + > + hdmi_register_notifier(&cec->nb); The notifier is registered here, but who provides CEC with the initial physical address? As I understand it, it only tells you when things change, not what the initial state is. Regards, Hans
Re: [PATCH 18/20] lib: image-formats: Add v4l2 formats support
Hi Maxime, On 4/17/19 9:54 AM, Maxime Ripard wrote: > V4L2 uses different fourcc's than DRM, and has a different set of formats. > For now, let's add the v4l2 fourcc's for the already existing formats. For this lib to be more useful for V4L2, would it be a good idea to add Bayer formats as well? This can be done in a separate patch. Those formats are V4L specific, but are very common. Regards, Hans > > Signed-off-by: Maxime Ripard > --- > include/linux/image-formats.h | 9 +- > lib/image-formats.c | 62 - > 2 files changed, 71 insertions(+) > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h > index ec43d9f9a527..b78b8e861fc9 100644 > --- a/include/linux/image-formats.h > +++ b/include/linux/image-formats.h > @@ -50,6 +50,13 @@ struct image_format_info { > }; > > /** > + * @v4l2_fmt: > + * > + * V4L2 4CC format identifier (V4L2_PIX_FMT_*) > + */ > + u32 v4l2_fmt; > + > + /** >* @depth: >* >* Color depth (number of bits per pixel excluding padding bits), > @@ -382,6 +389,8 @@ uint64_t image_format_info_min_pitch(const struct > image_format_info *info, > } > > const struct image_format_info *__image_format_drm_lookup(u32 drm); > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2); > const struct image_format_info *image_format_drm_lookup(u32 drm); > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2); > > #endif /* _IMAGE_FORMATS_H_ */ > diff --git a/lib/image-formats.c b/lib/image-formats.c > index 1e52a7410222..25fa22d243fb 100644 > --- a/lib/image-formats.c > +++ b/lib/image-formats.c > @@ -25,12 +25,14 @@ > #include > #include > #include > +#include > > #include > > static const struct image_format_info formats[] = { > { > .drm_fmt = DRM_FORMAT_C8, > + .v4l2_fmt = V4L2_PIX_FMT_GREY, > .depth = 8, > .num_planes = 1, > .cpp = { 1, 0, 0 }, > @@ -38,6 +40,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_RGB332, > + .v4l2_fmt = V4L2_PIX_FMT_RGB332, > .depth = 8, > .num_planes = 1, > .cpp = { 1, 0, 0 }, > @@ -172,6 +175,7 @@ static const struct image_format_info formats[] = { > .has_alpha = true, > }, { > .drm_fmt = DRM_FORMAT_RGB565, > + .v4l2_fmt = V4L2_PIX_FMT_RGB565X, > .depth = 16, > .num_planes = 1, > .cpp = { 2, 0, 0 }, > @@ -186,6 +190,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_RGB888, > + .v4l2_fmt = V4L2_PIX_FMT_BGR24, > .depth = 24, > .num_planes = 1, > .cpp = { 3, 0, 0 }, > @@ -193,6 +198,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_BGR888, > + .v4l2_fmt = V4L2_PIX_FMT_RGB24, > .depth = 24, > .num_planes = 1, > .cpp = { 3, 0, 0 }, > @@ -200,6 +206,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_XRGB, > + .v4l2_fmt = V4L2_PIX_FMT_XBGR32, > .depth = 24, > .num_planes = 1, > .cpp = { 4, 0, 0 }, > @@ -304,6 +311,7 @@ static const struct image_format_info formats[] = { > .has_alpha = true, > }, { > .drm_fmt = DRM_FORMAT_ARGB, > + .v4l2_fmt = V4L2_PIX_FMT_ABGR32, > .depth = 32, > .num_planes = 1, > .cpp = { 4, 0, 0 }, > @@ -384,6 +392,7 @@ static const struct image_format_info formats[] = { > .has_alpha = true, > }, { > .drm_fmt = DRM_FORMAT_YUV410, > + .v4l2_fmt = V4L2_PIX_FMT_YUV410, > .depth = 0, > .num_planes = 3, > .cpp = { 1, 1, 1 }, > @@ -392,6 +401,7 @@ static const struct image_format_info formats[] = { > .is_yuv = true, > }, { > .drm_fmt = DRM_FORMAT_YVU410, > + .v4l2_fmt = V4L2_PIX_FMT_YVU410, > .depth = 0, > .num_planes = 3, > .cpp = { 1, 1, 1 }, > @@ -416,6 +426,7 @@ static const struct image_format_info formats[] = { > .is_yuv = true, > }, { > .drm_fmt = DRM_FORMAT_YUV420, > + .v4l2_fmt = V4L2_PIX_FMT_YUV420, > .depth = 0, > .num_planes = 3, > .cpp = { 1, 1, 1 }, > @@ -424,6 +435,7 @@ static const struct image_format_info formats[] = { > .is_yuv = true, > }, { > .drm_fmt
Re: [PATCH 00/20] drm: Split out the formats API and move it to a common place
Hi Maxime, Apologies for the late reply, most if this thread happened when I was on vacation, and I missed that I should reply to it. Thank you for reminding me. Please let me know if I should reply to other mails in the discussion of this patch series. On 4/18/19 10:56 PM, Maxime Ripard wrote: > On Thu, Apr 18, 2019 at 02:32:14PM +0200, Daniel Vetter wrote: >> Unifying the formats themselves, and all the associated metadata is >> imo a no-go, and was a pretty conscious decision when we implemented >> drm_fourcc a few years back. >> >>> If we want to keep the current library in DRM, we have two options >>> then: >>> >>> - Support all the v4l2 formats in the DRM library, which is >>> essentially what I'm doing in the last patches. However, that >>> would require to have the v4l2 developpers also reviewing stuff >>> there. And given how busy they are, I cannot really see how that >>> would work. >> >> Well, if we end up with a common library then yes we need cross >> review. There's no way around that. Doesn't matter where exactly that >> library is in the filesystem tree, and adding a special MAINTAINERS >> entry for anything related to fourcc (both drm and v4l) to make sure >> they get cross-posted is easy. No file renaming needed. > > That would create some governing issues as well. For example, if you > ever have a patch from one fourcc addition (that might or might not be > covered by v4l2), will you wait for any v4l2 developper to review it? None of this is fixed by code renaming or locations. Either way we need to figure that out. And yes part of the reasons for not moving this out of drm is that I'm not a fan of boutique trees for small stuff. If sharing means we need to split the drm_fourcc code and library out of drm trees, I'm not sure that's a good idea. We're already super liberal with merging anything through driver trees with acks, and integrating them quickly into drm-next. This would still be workable if v4l sends regular pull requests to drm-next (every 1-2 weeks, like the other big gpu trees do). If we can only sync up once per merge window with a shared boutique tree for formats only, life is going to be painful. >>> >>> I don't get why we want to turn DRM into some kind of a black hole >>> that would pull everything. We don't have to, really. And at the same >>> time it carries the message that v4l2 is less important than DRM for >>> some reason, which I'm really not comfortable with. >> >> Make another tree somewhere that pulls in trees more often than every >> merge window, and I'm happy. It's the coordination effort of lots of >> trees that creates the black hole, not the other way round. Yes topic >> trees work, but if topic trees are persistent something with the >> organization of trees is wrong and needs to change. This very much >> looks like we'll end up with a perpetual topic branch for format stuff >> between drm and v4l. > > Well, if v4l2 sends a PR to DRM every 1 or 2 weeks, that definitely > looks like a topic branch to me. And on a far more frequent basis than > when we will merge a format description. > >> The other shared stuff (like hdmi infoframes) seems to change a lot >> less often, so the occasional patch hasn't been a pain. But drm_fourcc >> related stuff sees a lot of work, both in adding new formats and in >> refactoring the library to keep up with all the new use-cases. > > When was the last time a refactoring that changed the API happened? > > Most of the changes will be new format descriptions, and I guess that > would only concern a single tree. > > And really, we're doing this all the time, so I'm not sure what the > big deal is here. > > I feel like there's something that you don't really like about this, > but you're not saying this out loud. > > Sure, the exact process needs to be figured out, and everyone needs to > agree upon that process. But that's pretty much it, and it's nothing > out of the ordinary. > >> And yes I think an overall gfx-like-stuff.git tree for drm and v4l and >> the few other bits really makes tons of sense. Not as a tree where >> people commit, but as the 2nd-level integration tree (like drm.git >> right now for gpu stuff). >> >>> And I don't really get why you're against this in the first >>> place. When you have some code in a single driver that would benefit >>> more driver, you create a helper and move it into the core. >> >> It's a feature that drm doesn't share that much code with other parts >> of the kernel, it makes backporting the gfx stack to lts kernels a lot >> easier. Until someone fixes the upstream kernel release model to no >> longer need large scale gpu driver backports, we need to keep that. >> >>> In this case, we have some code used by a framework that more >>> framework could use, and we move it to a core-er place. How is that >>>
Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
Hi Maxime, Some comments below... On 3/19/19 10:57 PM, Maxime Ripard wrote: > V4L2 uses different fourcc's than DRM, and has a different set of formats. > For now, let's add the v4l2 fourcc's for the already existing formats. > > Signed-off-by: Maxime Ripard > --- > include/linux/image-formats.h | 9 +- > lib/image-formats.c | 67 - > 2 files changed, 76 insertions(+) > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h > index 53fd73a71b3d..fbc3a4501ebd 100644 > --- a/include/linux/image-formats.h > +++ b/include/linux/image-formats.h > @@ -26,6 +26,13 @@ struct image_format_info { > }; > > /** > + * @v4l2_fmt: > + * > + * V4L2 4CC format identifier (V4L2_PIX_FMT_*) > + */ > + u32 v4l2_fmt; > + > + /** >* @depth: >* >* Color depth (number of bits per pixel excluding padding bits), > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct > image_format_info *info) > > const struct image_format_info *__image_format_drm_lookup(u32 drm); > const struct image_format_info *image_format_drm_lookup(u32 drm); > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2); > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2); > unsigned int image_format_plane_cpp(const struct image_format_info *format, > int plane); > unsigned int image_format_plane_width(int width, > diff --git a/lib/image-formats.c b/lib/image-formats.c > index 9b9a73220c5d..39f1d38ae861 100644 > --- a/lib/image-formats.c > +++ b/lib/image-formats.c > @@ -8,6 +8,7 @@ > static const struct image_format_info formats[] = { > { > .drm_fmt = DRM_FORMAT_C8, > + .v4l2_fmt = V4L2_PIX_FMT_GREY, > .depth = 8, > .num_planes = 1, > .cpp = { 1, 0, 0 }, > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_RGB332, > + .v4l2_fmt = V4L2_PIX_FMT_RGB332, > .depth = 8, > .num_planes = 1, > .cpp = { 1, 0, 0 }, > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_XRGB, > + .v4l2_fmt = V4L2_PIX_FMT_XRGB444, > .depth = 0, > .num_planes = 1, > .cpp = { 2, 0, 0 }, > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_ARGB, > + .v4l2_fmt = V4L2_PIX_FMT_ARGB444, > .depth = 0, > .num_planes = 1, > .cpp = { 2, 0, 0 }, > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = { > .has_alpha = true, > }, { > .drm_fmt = DRM_FORMAT_XRGB1555, > + .v4l2_fmt = V4L2_PIX_FMT_XRGB555, > .depth = 15, > .num_planes = 1, > .cpp = { 2, 0, 0 }, > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_ARGB1555, > + .v4l2_fmt = V4L2_PIX_FMT_ARGB555, > .depth = 15, > .num_planes = 1, > .cpp = { 2, 0, 0 }, > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = { > .has_alpha = true, > }, { > .drm_fmt = DRM_FORMAT_RGB565, > + .v4l2_fmt = V4L2_PIX_FMT_RGB565, > .depth = 16, > .num_planes = 1, > .cpp = { 2, 0, 0 }, > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_RGB888, > + .v4l2_fmt = V4L2_PIX_FMT_RGB24, The V4L2 pixelformats describe the order of the components in memory, and as such are independent of the CPU endianness. How is that for the DRM formats? Will the order of DRM_FORMAT_RGB888 in memory differ between little and big endian systems? Mind you, V4L2 drivers are frankly never tested on big endian systems and I suspect many if not all will fail miserably on details like this. > .depth = 24, > .num_planes = 1, > .cpp = { 3, 0, 0 }, > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_BGR888, > + .v4l2_fmt = V4L2_PIX_FMT_BGR24, > .depth = 24, > .num_planes = 1, > .cpp = { 3, 0, 0 }, > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = { > .vsub = 1, > }, { > .drm_fmt = DRM_FORMAT_XRGB, > + .v4l2_fmt = V4L2_PIX_FMT
Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
On 4/11/19 9:12 AM, Hans Verkuil wrote: > Hi Maxime, > > Some comments below... > > On 3/19/19 10:57 PM, Maxime Ripard wrote: >> V4L2 uses different fourcc's than DRM, and has a different set of formats. >> For now, let's add the v4l2 fourcc's for the already existing formats. >> >> Signed-off-by: Maxime Ripard >> --- >> include/linux/image-formats.h | 9 +- >> lib/image-formats.c | 67 - >> 2 files changed, 76 insertions(+) >> >> diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h >> index 53fd73a71b3d..fbc3a4501ebd 100644 >> --- a/include/linux/image-formats.h >> +++ b/include/linux/image-formats.h >> @@ -26,6 +26,13 @@ struct image_format_info { >> }; >> >> /** >> + * @v4l2_fmt: >> + * >> + * V4L2 4CC format identifier (V4L2_PIX_FMT_*) >> + */ >> +u32 v4l2_fmt; >> + >> +/** >> * @depth: >> * >> * Color depth (number of bits per pixel excluding padding bits), >> @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct >> image_format_info *info) >> >> const struct image_format_info *__image_format_drm_lookup(u32 drm); >> const struct image_format_info *image_format_drm_lookup(u32 drm); >> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2); >> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2); >> unsigned int image_format_plane_cpp(const struct image_format_info *format, >> int plane); >> unsigned int image_format_plane_width(int width, >> diff --git a/lib/image-formats.c b/lib/image-formats.c >> index 9b9a73220c5d..39f1d38ae861 100644 >> --- a/lib/image-formats.c >> +++ b/lib/image-formats.c >> @@ -8,6 +8,7 @@ >> static const struct image_format_info formats[] = { >> { >> .drm_fmt = DRM_FORMAT_C8, >> +.v4l2_fmt = V4L2_PIX_FMT_GREY, >> .depth = 8, >> .num_planes = 1, >> .cpp = { 1, 0, 0 }, >> @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_RGB332, >> +.v4l2_fmt = V4L2_PIX_FMT_RGB332, >> .depth = 8, >> .num_planes = 1, >> .cpp = { 1, 0, 0 }, >> @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_XRGB, >> +.v4l2_fmt = V4L2_PIX_FMT_XRGB444, >> .depth = 0, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_ARGB, >> +.v4l2_fmt = V4L2_PIX_FMT_ARGB444, >> .depth = 0, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = { >> .has_alpha = true, >> }, { >> .drm_fmt = DRM_FORMAT_XRGB1555, >> +.v4l2_fmt = V4L2_PIX_FMT_XRGB555, >> .depth = 15, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_ARGB1555, >> +.v4l2_fmt = V4L2_PIX_FMT_ARGB555, >> .depth = 15, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = { >> .has_alpha = true, >> }, { >> .drm_fmt = DRM_FORMAT_RGB565, >> +.v4l2_fmt = V4L2_PIX_FMT_RGB565, >> .depth = 16, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_RGB888, >> +.v4l2_fmt = V4L2_PIX_FMT_RGB24, > > The V4L2 pixelformats describe the order of the components in memory, and as > such are independent of the CPU endianness. How is that for the DRM formats? > > Will the order of DRM_FORMAT_RGB888 in memory differ between little and big > end
Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
On 4/1/19 4:44 PM, Maxime Ripard wrote: > Hi Nicolas, > > On Fri, Mar 22, 2019 at 03:55:19PM -0400, Nicolas Dufresne wrote: >> Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : >>> V4L2 uses different fourcc's than DRM, and has a different set of formats. >>> For now, let's add the v4l2 fourcc's for the already existing formats. >> >> Hopefully I get the fixup right this time, see inline. > > Thanks a lot for that extensive review. > > About the single vs multi-planar issue, I'd be inclined with just > supporting single-planar formats for now, and extend it later to deal > with multiplanar formats. > > Would that work for everyone? I'd say that is the right approach. Regards, Hans > > Maxime > > -- > Maxime Ripard, Bootlin > Embedded Linux and Kernel engineering > https://bootlin.com > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
On 3/22/19 8:55 PM, Nicolas Dufresne wrote: > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : >> V4L2 uses different fourcc's than DRM, and has a different set of formats. >> For now, let's add the v4l2 fourcc's for the already existing formats. > > Hopefully I get the fixup right this time, see inline. > >> >> Signed-off-by: Maxime Ripard >> --- >> include/linux/image-formats.h | 9 +- >> lib/image-formats.c | 67 - >> 2 files changed, 76 insertions(+) >> >> diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h >> index 53fd73a71b3d..fbc3a4501ebd 100644 >> --- a/include/linux/image-formats.h >> +++ b/include/linux/image-formats.h >> @@ -26,6 +26,13 @@ struct image_format_info { >> }; >> >> /** >> + * @v4l2_fmt: >> + * >> + * V4L2 4CC format identifier (V4L2_PIX_FMT_*) >> + */ >> +u32 v4l2_fmt; >> + >> +/** >> * @depth: >> * >> * Color depth (number of bits per pixel excluding padding bits), >> @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct >> image_format_info *info) >> >> const struct image_format_info *__image_format_drm_lookup(u32 drm); >> const struct image_format_info *image_format_drm_lookup(u32 drm); >> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2); >> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2); >> unsigned int image_format_plane_cpp(const struct image_format_info *format, >> int plane); >> unsigned int image_format_plane_width(int width, >> diff --git a/lib/image-formats.c b/lib/image-formats.c >> index 9b9a73220c5d..39f1d38ae861 100644 >> --- a/lib/image-formats.c >> +++ b/lib/image-formats.c >> @@ -8,6 +8,7 @@ >> static const struct image_format_info formats[] = { >> { >> .drm_fmt = DRM_FORMAT_C8, >> +.v4l2_fmt = V4L2_PIX_FMT_GREY, >> .depth = 8, >> .num_planes = 1, >> .cpp = { 1, 0, 0 }, >> @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_RGB332, >> +.v4l2_fmt = V4L2_PIX_FMT_RGB332, >> .depth = 8, >> .num_planes = 1, >> .cpp = { 1, 0, 0 }, >> @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_XRGB, >> +.v4l2_fmt = V4L2_PIX_FMT_XRGB444, > > Not completely sure, looks like in the V4L2 variant, the padding is on > the 4 MSB of the second byte, which makes it incompatible. There is no > other equivalent. > >> .depth = 0, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_ARGB, >> +.v4l2_fmt = V4L2_PIX_FMT_ARGB444, > > Similarly. > >> .depth = 0, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = { >> .has_alpha = true, >> }, { >> .drm_fmt = DRM_FORMAT_XRGB1555, >> +.v4l2_fmt = V4L2_PIX_FMT_XRGB555, > > Same swapping, can't find a match. > >> .depth = 15, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_ARGB1555, >> +.v4l2_fmt = V4L2_PIX_FMT_ARGB555, > > Same. > >> .depth = 15, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = { >> .has_alpha = true, >> }, { >> .drm_fmt = DRM_FORMAT_RGB565, >> +.v4l2_fmt = V4L2_PIX_FMT_RGB565, > > -> V4L2_PIX_FMT_RGB565X > > Was added later, as what you expect is not compatible. All these 16-bit V4L2 pixelformats are ancient, but they are (to my knowledge) correct w.r.t. the documented layout of the bits in memory. I.e., that's what the hardware will give you. I think if there is no equivalence between the drm and v4l2 fourcc's, then you need two entries in this table, one for drm (v4l2_fmt == 0), one for v4l2 (drm_fmt == 0). > >> .depth = 16, >> .num_planes = 1, >> .cpp = { 2, 0, 0 }, >> @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = { >> .vsub = 1, >> }, { >> .drm_fmt = DRM_FORMAT_RGB888, >> +.v4l2_fmt = V4L2_PIX_FMT_RGB24, > > -> V4L2_PIX_FMT_BGR24 > >> .depth = 24, >> .num_planes = 1, >> .cpp = { 3, 0, 0 }, >> @@ -170,6 +178,7 @@ static const struct im
Re: [PATCH v2 0/2] drm/sun4i: dw-hdmi: Improve CEC support
Hi Jernej, On 4/1/19 9:15 PM, Jernej Skrabec wrote: > It turns out that additional logic between HDMI CEC controller and > pins on PHY on some Allwinner SoCs prevents proper communication. > It might be possible to fix it, but it's much easier and less error > prone to just directly drive pins using software implementation of > CEC protocol. 1) Please CC linux-media as well, I had almost missed this series. 2) Is this a SoC limitation or a board limitation? 3) Is the bit-banging support sunxi specific? Or is it still using some DW CEC functionality? It appears to be sunxi specific. 4) I had an old patch series: https://www.spinics.net/lists/dri-devel/msg170232.html Rob Herring disagreed with that, but the discussion fizzled out at the end. I still think doing this in the device tree is the right approach since this is very much hardware related. If the DW CEC implementation doesn't work for some reason (CEC pins not hooked up, or for other reasons non-functional), then it should be disabled in the device tree. So then adding a new SUN8I option to enable bitbanging CEC support seems logical. Regards, Hans > > Let me know what do you think. > > Best regards, > Jernej > > Changes from v1: > - renamed is_cec_unusable to disable_cec > - added review-by tag > > Jernej Skrabec (2): > drm/bridge/synopsys: dw-hdmi: Add an option to suppress loading CEC > driver > drm/sun4i: dw-hdmi: Bit bang CEC on some SoCs > > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +- > drivers/gpu/drm/sun4i/Kconfig | 10 +++ > drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 11 +++ > drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c| 83 ++- > include/drm/bridge/dw_hdmi.h | 2 + > 5 files changed, 105 insertions(+), 3 deletions(-) > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel