Re: [PATCH 2/2] media: i2c: mt9t112: Add device tree support
Hi Sakari, On Tue, May 15, 2018 at 12:50:04AM +0300, Sakari Ailus wrote: > Hi Jacopo, > > On Mon, May 14, 2018 at 04:30:44PM +0200, jacopo mondi wrote: > > Hi Sakari, > > > > On Mon, May 07, 2018 at 12:32:19PM +0300, Sakari Ailus wrote: > > > Hi Jacopo, > > > > > > On Wed, Apr 25, 2018 at 01:00:14PM +0200, Jacopo Mondi wrote: > > > > [snip] > > > > > > static int mt9t112_probe(struct i2c_client *client, > > > > const struct i2c_device_id *did) > > > > { > > > > struct mt9t112_priv *priv; > > > > int ret; > > > > > > > > - if (!client->dev.platform_data) { > > > > + if (!client->dev.of_node && !client->dev.platform_data) { > > > > dev_err(&client->dev, "mt9t112: missing platform > > > > data!\n"); > > > > return -EINVAL; > > > > } > > > > @@ -1081,23 +1118,39 @@ static int mt9t112_probe(struct i2c_client > > > > *client, > > > > if (!priv) > > > > return -ENOMEM; > > > > > > > > - priv->info = client->dev.platform_data; > > > > priv->init_done = false; > > > > - > > > > - v4l2_i2c_subdev_init(&priv->subdev, client, > > > > &mt9t112_subdev_ops); > > > > - > > > > - priv->clk = devm_clk_get(&client->dev, "extclk"); > > > > - if (PTR_ERR(priv->clk) == -ENOENT) { > > > > + priv->dev = &client->dev; > > > > + > > > > + if (client->dev.platform_data) { > > > > + priv->info = client->dev.platform_data; > > > > + > > > > + priv->clk = devm_clk_get(&client->dev, "extclk"); > > > > > > extclk needs to be documented in DT binding documentation. > > > > > > > + if (PTR_ERR(priv->clk) == -ENOENT) { > > > > + priv->clk = NULL; > > > > + } else if (IS_ERR(priv->clk)) { > > > > + dev_err(&client->dev, > > > > + "Unable to get clock \"extclk\"\n"); > > > > + return PTR_ERR(priv->clk); > > > > + } > > > > + } else { > > > > + /* > > > > +* External clock frequencies != 24MHz are only > > > > supported > > > > +* for non-OF systems. > > > > +*/ > > > > > > Shouldn't you actually set the frequency? Or perhaps even better to check > > > it, and use assigned-clocks and assigned-clock-rates properties? > > > > > > > I might be confused, but my intention was to use an external clock > > reference, with a configurable frequency only in the platform data use > > case. As you can see in this 'else' branch, in OF case, the priv->clk > > field is null, and all the PLL and clock computations are performed > > assuming a 24MHz input clock. > > > > In my opinion, as the driver when running on OF systems does not > > get any reference to 'extclk' clock, it should not be documented in > > bindings. Do you agree? > > Uh, isn't the clock generally controlled by the driver on OF-based systems? > You could assign the frequency in DT though, and not in the driver, but > that should be documented in binding documentation. > > The register configuration the driver does not appear to be dependent on > the clock frequency, which suggests that it is only applicable to a > particular frequency --- 24 MHz? Correct. That's what the comment above here states... /* * External clock frequencies != 24MHz are only supported * for non-OF systems. */ That's how it works: the driver expects to receive the PLL dividers from platform data. It's ugly, I agree, but that's how it was. I do not have time atm to poke around with PLL configuration, and I'm not even sure I have the right documentation, so I made a 'default PLL configuration' for 24MHz clock, copied from the platform data supplied to the driver by the only user in mainline. In general, I would like to have the driver calculate the PLL dividers based on the input clock frequency, that should be supplied from DT. As this is not possible, at the moment I made the driver only provide a PLL configuration for 24MHz, and that's the only clock the driver accepts. + priv->info = &mt9t112_default_pdata_24MHz; Would you prefer I take a reference to an external clock, check it's frequency and refuse it if != 24MHz? By the way, I'm trying to run this driver with a camera module connected to an ARM platform and so far I have not been able to capture any image. The Ecovec I have (thanks Hans) has a camera module but the cable is bad, so I can't test it on the platform the driver has originally been developed on, but I assume on SH Ecovec it works properly. Any confirmation from someone who has that board would be appreciate though. Thanks j > > > > > Thanks > >j > > > > > > priv->clk = NULL; > > > > - } else if (IS_ERR(priv->clk)) { > > > > - dev_err(&client->dev, "Unable to get clock > > > > \"extclk\"\n"); > > > > -
Re: [PATCH] media: dt-bindings: media: rcar_vin: add support for r8a77965
On Sun, May 13, 2018 at 08:58:18PM +0200, Niklas Söderlund wrote: > Signed-off-by: Niklas Söderlund Reviewed-by: Simon Horman
Re: [PATCH v16 2/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Hi Niklas, thanks fro the patch. On Tue, May 15, 2018 at 02:56:35AM +0200, Niklas Söderlund wrote: > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver > supports the R-Car Gen3 SoCs where separate CSI-2 hardware blocks are > connected between the video sources and the video grabbers (VIN). > > Driver is based on a prototype by Koji Matsuoka in the Renesas BSP. > > Signed-off-by: Niklas Söderlund > Reviewed-by: Laurent Pinchart > Reviewed-by: Maxime Ripard I forgot to add it to v15, as my comments there pointed to non blocking issues. Reviewed-by: Jacopo Mondi Thanks j > > --- > > * Changes since v15 > - Merge struct phtw_mbps and struct phypll_hsfreqrange into a new struct > which maps a mpbs value to a register value, struct rcsi2_mbps_reg. > - Reduced number of loops and delay when waiting for LP-11 and > confirmation of PHTW write as suggested by Laurent. > - Dropped dev_dbg() printouts of the requested link speed. > - Fix small issues in comments. > - Remove unneeded () in for-loop condition in rcsi2_phtw_write_array(). > - Remove __refdata from declaration of 'static struct platform_driver > rcar_csi2_pdrv'. > - Update MODULE_DESCRIPTION to 'Renesas R-Car MIPI CSI-2 receiver > driver'. > - Fixed two erroneous values in hsfreqrange_h3_v3h_m3n[]. Thanks Jacopo > for spotting this! > - Max link speed for V3M and E3 are 1.125Gbps remove settings above that > limit in phtw_mbps_v3m_e3. This also changed in datasheet v1.0. > - Add review tags from Laurent and Maxime. > > * Changes since v14 > - Data sheet update changed init sequence for PHY forcing a restructure > of the driver. The restructure was so big I felt compel to drop all > review tags :-( > - The change was that the Renesas H3 procedure was aligned with other > SoC in the Gen3 family procedure. I had kept the rework as separate > patches and was planing to post once original driver with H3 and M3-W > support where merged. As review tags are dropped I chosen to squash > those patches into 2/2. > - Add support for Gen3 V3M. > - Add support for Gen3 M3-N. > - Set PHTC_TESTCLR when stopping the PHY. > - Revert back to the v12 and earlier phypll calculation as it turns out > it was correct after all. > > * Changes since v13 > - Change return rcar_csi2_formats + i to return &rcar_csi2_formats[i]. > - Add define for PHCLM_STOPSTATECKL. > - Update spelling in comments. > - Update calculation in rcar_csi2_calc_phypll() according to > https://linuxtv.org/downloads/v4l-dvb-apis/kapi/csi2.html. The one > before v14 did not take into account that 2 bits per sample is > transmitted. > - Use Geert's suggestion of (1 << priv->lanes) - 1 instead of switch > statement to set correct number of lanes to enable. > - Change hex constants in hsfreqrange_m3w_h3es1[] to lower case to match > style of rest of file. > - Switch to %u instead of 0x%x when printing bus type. > - Switch to %u instead of %d for priv->lanes which is unsigned. > - Add MEDIA_BUS_FMT_YUYV8_1X16 to the list of supported formats in > rcar_csi2_formats[]. > - Fixed bps for MEDIA_BUS_FMT_YUYV10_2X10 to 20 and not 16. > - Set INTSTATE after PL-11 is confirmed to match flow chart in > datasheet. > - Change priv->notifier.subdevs == NULL to !priv->notifier.subdevs. > - Add Maxime's and laurent's tags. > --- > drivers/media/platform/rcar-vin/Kconfig | 12 + > drivers/media/platform/rcar-vin/Makefile|1 + > drivers/media/platform/rcar-vin/rcar-csi2.c | 1084 +++ > 3 files changed, 1097 insertions(+) > create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c > > diff --git a/drivers/media/platform/rcar-vin/Kconfig > b/drivers/media/platform/rcar-vin/Kconfig > index 8fa7ee468c63afb9..d5835da6d4100d87 100644 > --- a/drivers/media/platform/rcar-vin/Kconfig > +++ b/drivers/media/platform/rcar-vin/Kconfig > @@ -1,3 +1,15 @@ > +config VIDEO_RCAR_CSI2 > + tristate "R-Car MIPI CSI-2 Receiver" > + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF > + depends on ARCH_RENESAS || COMPILE_TEST > + select V4L2_FWNODE > + help > + Support for Renesas R-Car MIPI CSI-2 receiver. > + Supports R-Car Gen3 SoCs. > + > + To compile this driver as a module, choose M here: the > + module will be called rcar-csi2. > + > config VIDEO_RCAR_VIN > tristate "R-Car Video Input (VIN) Driver" > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && > MEDIA_CONTROLLER > diff --git a/drivers/media/platform/rcar-vin/Makefile > b/drivers/media/platform/rcar-vin/Makefile > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 > --- a/drivers/media/platform/rcar-vin/Makefile > +++ b/drivers/media/platform/rcar-vin/Makefile > @@ -1,3 +1,4 @@ > rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o > > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o > obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o > diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c > b/drivers/media/platform/r
[PATCH] cec: improve cec status documentation
Clarify the description of status bits, particularly w.r.t. ERROR and NACK. Signed-off-by: Hans Verkuil --- diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index a9f53f069a2d..1d989c544370 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -246,7 +246,10 @@ CEC_TX_STATUS_LOW_DRIVE: CEC_TX_STATUS_ERROR: some unspecified error occurred: this can be one of ARB_LOST or LOW_DRIVE if the hardware cannot differentiate or something - else entirely. + else entirely. Some hardware only supports OK and FAIL as the + result of a transmit, i.e. there is no way to differentiate + between the different possible errors. In that case map FAIL + to CEC_TX_STATUS_NACK and not to CEC_TX_STATUS_ERROR. CEC_TX_STATUS_MAX_RETRIES: could not transmit the message after trying multiple times. diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index bdad4b197bcd..e964074cd15b 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -231,26 +231,32 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). - ``CEC_TX_STATUS_OK`` - 0x01 - The message was transmitted successfully. This is mutually - exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES `. Other bits can still - be set if earlier attempts met with failure before the transmit - was eventually successful. + exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES `. + Other bits can still be set if earlier attempts met with failure before + the transmit was eventually successful. * .. _`CEC-TX-STATUS-ARB-LOST`: - ``CEC_TX_STATUS_ARB_LOST`` - 0x02 - - CEC line arbitration was lost. + - CEC line arbitration was lost, i.e. another transmit started at the +same time with a higher priority. Optional status, not all hardware + can detect this error condition. * .. _`CEC-TX-STATUS-NACK`: - ``CEC_TX_STATUS_NACK`` - 0x04 - - Message was not acknowledged. + - Message was not acknowledged. Note that some hardware cannot tell apart +a 'Not Acknowledged' status from other error conditions, i.e. the result + of a transmit is just OK or FAIL. In that case this status will be + returned when the transmit failed. * .. _`CEC-TX-STATUS-LOW-DRIVE`: - ``CEC_TX_STATUS_LOW_DRIVE`` - 0x08 - Low drive was detected on the CEC bus. This indicates that a follower detected an error on the bus and requests a - retransmission. + retransmission. Optional status, not all hardware can detect this + error condition. * .. _`CEC-TX-STATUS-ERROR`: - ``CEC_TX_STATUS_ERROR`` @@ -258,14 +264,14 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). - Some error occurred. This is used for any errors that do not fit ``CEC_TX_STATUS_ARB_LOST`` or ``CEC_TX_STATUS_LOW_DRIVE``, either because the hardware could not tell which error occurred, or because the hardware - tested for other conditions besides those two. + tested for other conditions besides those two. Optional status. * .. _`CEC-TX-STATUS-MAX-RETRIES`: - ``CEC_TX_STATUS_MAX_RETRIES`` - 0x20 - The transmit failed after one or more retries. This status bit is - mutually exclusive with :ref:`CEC_TX_STATUS_OK `. Other bits can still - be set to explain which failures were seen. + mutually exclusive with :ref:`CEC_TX_STATUS_OK `. + Other bits can still be set to explain which failures were seen. .. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
Re: [RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver
Hi Hans, Thanks for the extensive review. On 15/05/2018 08:58, Hans Verkuil wrote: > On 05/15/2018 12:40 AM, Neil Armstrong wrote: >> The Chrome OS Embedded Controller can expose a CEC bus, this patch add the >> driver for such feature of the Embedded Controller. >> >> This driver is part of the cros-ec MFD and will be add as a sub-device when >> the feature bit is exposed by the EC. >> >> The controller will only handle a single logical address and handles >> all the messages retries and will only expose Success or Error. >> >> When the logical address is invalid, the controller will act as a CEC sniffer >> and transfer all messages on the bus. > > I did not see any support for this. If this works as you state here, then > adding > support for CEC_CAP_MONITOR_ALL is highly recommended. Oops, I forgot to remove this phrase, the FW will maybe support it, but it has been dropped for the first revision. > >> >> Signed-off-by: Neil Armstrong >> --- >> drivers/media/platform/Kconfig | 11 + >> drivers/media/platform/Makefile | 2 + >> drivers/media/platform/cros-ec/Makefile | 1 + >> drivers/media/platform/cros-ec/cros-ec-cec.c | 331 >> +++ >> 4 files changed, 345 insertions(+) >> create mode 100644 drivers/media/platform/cros-ec/Makefile >> create mode 100644 drivers/media/platform/cros-ec/cros-ec-cec.c > > Shouldn't the directory be called cros-ec-cec? > >> >> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig >> index c7a1cf8..e55a8ed2 100644 >> --- a/drivers/media/platform/Kconfig >> +++ b/drivers/media/platform/Kconfig >> @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS >> >> if CEC_PLATFORM_DRIVERS >> >> +config VIDEO_CROS_EC_CEC >> +tristate "Chrome OS EC CEC driver" >> +depends on MFD_CROS_EC || COMPILE_TEST >> +select CEC_CORE >> +select CEC_NOTIFIER >> +---help--- >> + If you say yes here you will get support for the >> + Chrome OS Embedded Controller's CEC. >> + The CEC bus is present in the HDMI connector and enables communication >> + between compatible devices. >> + >> config VIDEO_MESON_AO_CEC >> tristate "Amlogic Meson AO CEC driver" >> depends on ARCH_MESON || COMPILE_TEST >> diff --git a/drivers/media/platform/Makefile >> b/drivers/media/platform/Makefile >> index 932515d..0e0582e 100644 >> --- a/drivers/media/platform/Makefile >> +++ b/drivers/media/platform/Makefile >> @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += >> qcom/camss-8x16/ >> obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ >> >> obj-y += meson/ >> + >> +obj-y += cros-ec/ >> diff --git a/drivers/media/platform/cros-ec/Makefile >> b/drivers/media/platform/cros-ec/Makefile >> new file mode 100644 >> index 000..9ce97f9 >> --- /dev/null >> +++ b/drivers/media/platform/cros-ec/Makefile >> @@ -0,0 +1 @@ >> +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o >> diff --git a/drivers/media/platform/cros-ec/cros-ec-cec.c >> b/drivers/media/platform/cros-ec/cros-ec-cec.c >> new file mode 100644 >> index 000..fea90da >> --- /dev/null >> +++ b/drivers/media/platform/cros-ec/cros-ec-cec.c >> @@ -0,0 +1,331 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * CEC driver for Chrome OS Embedded Controller >> + * >> + * Copyright (c) 2018 BayLibre, SAS >> + * Author: Neil Armstrong >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define DRV_NAME"cros-ec-cec" >> + >> +/** >> + * struct cros_ec_cec - Driver data for EC CEC >> + * >> + * @cros_ec: Pointer to EC device >> + * @notifier: Notifier info for responding to EC events >> + * @adap: CEC adapter >> + * @notify: CEC notifier pointer >> + * @rc_msg: storage for a received message >> + */ >> +struct cros_ec_cec { >> +struct cros_ec_device *cros_ec; >> +struct notifier_block notifier; >> +struct cec_adapter *adap; >> +struct cec_notifier *notify; >> +struct cec_msg rx_msg; >> +}; >> + >> +static void handle_cec_message(struct cros_ec_cec *cros_ec_cec) >> +{ >> +struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; >> +uint8_t *cec_message = cros_ec->event_data.data.cec_message; >> +unsigned int len = cros_ec->event_size; >> + >> +cros_ec_cec->rx_msg.len = len; > > How robust is the underlying code and hardware? What happens if a > CEC message with more than 16 bytes is received? > > Hard to test unless you have an RPi3 set up as a CEC debugger. See > last section in https://hverkuil.home.xs4all.nl/cec-status.txt. > > Since you worked with CEC for a while now I recommend you set up such > a system. It's cheap and very useful. I will definitely setup this kind of system, I tried using am Amlogic SoC, but it really can't monitor the bus But I a
Re: [RFC PATCH 2/5] media: cec-notifier: Get notifier by device and connector name
On 15/05/2018 08:27, Hans Verkuil wrote: > Hi Neil, > > Thanks for this patch series! > > Some comments below: > > On 05/15/2018 12:40 AM, Neil Armstrong wrote: >> In non device-tree world, we can need to get the notifier by the driver >> name directly and eventually defer probe if not yet created. >> >> This patch adds a variant of the get function by using the device name >> instead and will not create a notifier if not yet created. >> >> But the i915 driver exposes at least 2 HDMI connectors, this patch also >> adds the possibility to add a connector name tied to the notifier device >> to form a tuple and associate different CEC controllers for each HDMI >> connectors. >> >> Signed-off-by: Neil Armstrong >> --- >> drivers/media/cec/cec-notifier.c | 30 --- >> include/media/cec-notifier.h | 44 >> ++-- >> 2 files changed, 69 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/media/cec/cec-notifier.c >> b/drivers/media/cec/cec-notifier.c >> index 16dffa0..716070a 100644 >> --- a/drivers/media/cec/cec-notifier.c >> +++ b/drivers/media/cec/cec-notifier.c >> @@ -21,6 +21,7 @@ struct cec_notifier { >> struct list_head head; >> struct kref kref; >> struct device *dev; >> +const char *conn; >> struct cec_adapter *cec_adap; >> void (*callback)(struct cec_adapter *adap, u16 pa); >> >> @@ -30,13 +31,34 @@ struct cec_notifier { >> static LIST_HEAD(cec_notifiers); >> static DEFINE_MUTEX(cec_notifiers_lock); >> >> -struct cec_notifier *cec_notifier_get(struct device *dev) >> +struct cec_notifier *cec_notifier_get_byname(const char *name, >> + const char *conn) >> { >> struct cec_notifier *n; >> >> mutex_lock(&cec_notifiers_lock); >> list_for_each_entry(n, &cec_notifiers, head) { >> -if (n->dev == dev) { >> +if (!strcmp(dev_name(n->dev), name) && >> +(!conn || !strcmp(n->conn, conn))) { >> +kref_get(&n->kref); >> +mutex_unlock(&cec_notifiers_lock); >> +return n; >> +} >> +} >> +mutex_unlock(&cec_notifiers_lock); >> + >> +return NULL; > > This doesn't seem right. For one it doesn't act like the other > cec_notifier_get* > functions in that it doesn't make a new notifier if it wasn't found yet in the > list. > > For another, I think this function shouldn't be here at all. How about calling > bus_find_device_by_name(), then use cec_notifier_get_conn()? Yes, it's safer and will keep the original cec_notifier_get() behavior. > >> +} >> +EXPORT_SYMBOL_GPL(cec_notifier_get_byname); >> + >> +struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char >> *conn) >> +{ >> +struct cec_notifier *n; >> + >> +mutex_lock(&cec_notifiers_lock); >> +list_for_each_entry(n, &cec_notifiers, head) { >> +if (n->dev == dev && >> +(!conn || !strcmp(n->conn, conn))) { >> kref_get(&n->kref); >> mutex_unlock(&cec_notifiers_lock); >> return n; >> @@ -46,6 +68,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev) >> if (!n) >> goto unlock; >> n->dev = dev; >> +if (conn) >> +n->conn = devm_kstrdup(dev, conn, GFP_KERNEL); > > The use of devm_kstrdup worries me. The problem is that when the 'dev' device > is removed, this memory is also automatically freed. But the notifier might > still have a reference through the CEC driver, so you end up with a n->conn > pointer that points to freed memory. > > I think it is better to just use kstrdup and kfree it when the last notifier > reference is released. Ok > >> n->phys_addr = CEC_PHYS_ADDR_INVALID; >> mutex_init(&n->lock); >> kref_init(&n->kref); >> @@ -54,7 +78,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev) >> mutex_unlock(&cec_notifiers_lock); >> return n; >> } >> -EXPORT_SYMBOL_GPL(cec_notifier_get); >> +EXPORT_SYMBOL_GPL(cec_notifier_get_conn); >> >> static void cec_notifier_release(struct kref *kref) >> { >> diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h >> index cf0add7..70f2974 100644 >> --- a/include/media/cec-notifier.h >> +++ b/include/media/cec-notifier.h >> @@ -20,6 +20,37 @@ struct cec_notifier; >> #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) >> >> /** >> + * cec_notifier_get_byname - find a cec_notifier for the given device name >> + * and connector tuple. >> + * @name: device name that sends the events. >> + * @conn: the connector name from which the event occurs >> + * >> + * If a notifier for device @name exists, then increase the refcount and >> + * return that notifier. >> + * >> + * If it doesn't exist, return NULL >> + */ >> +struct cec_notifier *cec_notifier_get_byname(const char *name, >> +
Re: [RFC PATCH 3/5] drm/i915: hdmi: add CEC notifier to intel_hdmi
On 15/05/2018 08:34, Hans Verkuil wrote: > On 05/15/2018 12:40 AM, Neil Armstrong wrote: >> This patchs adds the cec_notifier feature to the intel_hdmi part >> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate >> between each HDMI ports. >> The changes will allow the i915 HDMI code to notify EDID and HPD changes >> to an eventual CEC adapter. >> >> Signed-off-by: Neil Armstrong >> --- >> drivers/gpu/drm/i915/intel_drv.h | 2 ++ >> drivers/gpu/drm/i915/intel_hdmi.c | 10 ++ > > The Kconfig also needs to be changed. In the DRM_I915 you need to add: > > select CEC_CORE if CEC_NOTIFIER OK, thanks > > Otherwise you'll get problems if the cec driver is a module and i915 is > built-in. > > Regards, > > Hans >
Re: Are media drivers abusing of GFP_DMA? - was: Re: [LSF/MM TOPIC NOTES] x86 ZONE_DMA love
On 14/05/18 12:39, Mauro Carvalho Chehab wrote: > Em Mon, 14 May 2018 07:35:03 -0300 > Mauro Carvalho Chehab escreveu: > >> Hi Fabien, >> >> Em Mon, 14 May 2018 08:00:37 + >> Fabien DESSENNE escreveu: >> >>> On 07/05/18 17:19, Mauro Carvalho Chehab wrote: Em Mon, 07 May 2018 16:26:08 +0300 Laurent Pinchart escreveu: > Hi Mauro, > > On Saturday, 5 May 2018 19:08:15 EEST Mauro Carvalho Chehab wrote: >> There was a recent discussion about the use/abuse of GFP_DMA flag when >> allocating memories at LSF/MM 2018 (see Luis notes enclosed). >> >> The idea seems to be to remove it, using CMA instead. Before doing that, >> better to check if what we have on media is are valid use cases for it, >> or >> if it is there just due to some misunderstanding (or because it was >> copied from some other code). >> >> Hans de Goede sent us today a patch stopping abuse at gspca, and I'm >> also posting today two other patches meant to stop abuse of it on USB >> drivers. Still, there are 4 platform drivers using it: >> >> $ git grep -l -E "GFP_DMA\\b" drivers/media/ >> drivers/media/platform/omap3isp/ispstat.c >> drivers/media/platform/sti/bdisp/bdisp-hw.c >> drivers/media/platform/sti/hva/hva-mem.c >>> Hi Mauro, >>> >>> The two STI drivers (bdisp-hw.c and hva-mem.c) are only expected to run >>> on ARM platforms, not on x86. >>> Since this thread deals with x86 & DMA trouble, I am not sure that we >>> actually have a problem for the sti drivers. >>> >>> There are some other sti drivers that make use of this GFP_DMA flag >>> (drivers/gpu/drm/sti/sti_*.c) and it does not seem to be a problem. >>> >>> Nevertheless I can see that the media sti drivers depend on COMPILE_TEST >>> (which is not the case for the DRM ones). >>> Would it be an acceptable solution to remove the COMPILE_TEST dependency? >> This has nothing to do with either x86 or COMPILE_TEST. The thing is >> that there's a plan for removing GFP_DMA from the Kernel[1], as it was >> originally meant to be used only by old PCs, where the DMA controllers >> used only on the bottom 16 MB memory address (24 bits). IMHO, it is >> very unlikely that any ARM SoC have such limitation. >> >> [1] https://lwn.net/Articles/753273/ (article will be freely available >> on May, 17) > Btw, you can also read about that at: > https://lwn.net/Articles/753274/ > >> Anyway, before the removal of GFP_DMA happens, I'd like to better >> understand why we're using it at media, and if we can, instead, >> set the DMA bit mask, just like almost all other media drivers >> that require to confine DMA into a certain range do. In the case >> of ARM, this is what we currently have: >> >> drivers/media/platform/exynos-gsc/gsc-core.c: >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); >> drivers/media/platform/exynos4-is/fimc-core.c: >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); >> drivers/media/platform/exynos4-is/fimc-is.c: >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); >> drivers/media/platform/exynos4-is/fimc-lite.c: >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); >> drivers/media/platform/mtk-mdp/mtk_mdp_core.c: >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); >> drivers/media/platform/omap3isp/isp.c: ret = >> dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); >> drivers/media/platform/s5p-g2d/g2d.c: >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); >> drivers/media/platform/s5p-jpeg/jpeg-core.c: >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); >> drivers/media/platform/s5p-mfc/s5p_mfc.c: >>DMA_BIT_MASK(32)); >> drivers/media/platform/s5p-mfc/s5p_mfc.c: >>DMA_BIT_MASK(32)); >> drivers/media/platform/s5p-mfc/s5p_mfc.c: >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); >> That's clearer now, thank you for the clarification I am about to send patches for the sti drivers (set the DMA bit mask) BR, Fabien >>> BR >>> >>> Fabien >>> >> drivers/media/spi/cxd2880-spi.c >> >> Could you please check if GFP_DMA is really needed there, or if it is >> just because of some cut-and-paste from some other place? > I started looking at that for the omap3isp driver but Sakari beat me at > submitting a patch. GFP_DMA isn't needed for omap3isp. > Thank you both for looking into it. Regards, Mauro Thanks, Mauro >> >> >> Thanks, >> Mauro > > > Thanks, > Mauro
Re: [RFC PATCH 3/5] drm/i915: hdmi: add CEC notifier to intel_hdmi
On 15/05/2018 08:29, Hans Verkuil wrote: > On 05/15/2018 12:40 AM, Neil Armstrong wrote: >> This patchs adds the cec_notifier feature to the intel_hdmi part >> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate >> between each HDMI ports. >> The changes will allow the i915 HDMI code to notify EDID and HPD changes >> to an eventual CEC adapter. >> >> Signed-off-by: Neil Armstrong >> --- >> drivers/gpu/drm/i915/intel_drv.h | 2 ++ >> drivers/gpu/drm/i915/intel_hdmi.c | 10 ++ >> 2 files changed, 12 insertions(+) >> >> diff --git a/drivers/gpu/drm/i915/intel_drv.h >> b/drivers/gpu/drm/i915/intel_drv.h >> index d436858..b50e51b 100644 >> --- a/drivers/gpu/drm/i915/intel_drv.h >> +++ b/drivers/gpu/drm/i915/intel_drv.h >> @@ -39,6 +39,7 @@ >> #include >> #include >> #include >> +#include >> >> /** >> * __wait_for - magic wait macro >> @@ -1001,6 +1002,7 @@ struct intel_hdmi { >> bool has_audio; >> bool rgb_quant_range_selectable; >> struct intel_connector *attached_connector; >> +struct cec_notifier *notifier; >> }; >> >> struct intel_dp_mst_encoder; >> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c >> b/drivers/gpu/drm/i915/intel_hdmi.c >> index 1baef4a..9b94d72 100644 >> --- a/drivers/gpu/drm/i915/intel_hdmi.c >> +++ b/drivers/gpu/drm/i915/intel_hdmi.c >> @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) >> connected = true; >> } >> >> +cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid); >> + >> return connected; >> } >> >> @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, >> bool force) >> { >> enum drm_connector_status status; >> struct drm_i915_private *dev_priv = to_i915(connector->dev); >> +struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); >> >> DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", >>connector->base.id, connector->name); >> @@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, >> bool force) >> >> intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); >> >> +if (status != connector_status_connected) >> +cec_notifier_phys_addr_invalidate(intel_hdmi->notifier); >> + >> return status; >> } >> >> @@ -2358,6 +2364,10 @@ void intel_hdmi_init_connector(struct >> intel_digital_port *intel_dig_port, >> u32 temp = I915_READ(PEG_BAND_GAP_DATA); >> I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); >> } >> + >> +intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name); >> +if (!intel_hdmi->notifier) >> +DRM_DEBUG_KMS("CEC notifier get failed\n"); > > You 'get' the notifier here, but where is the cec_notifier_put when the > connector is deleted? Because I failed to find a safe place for this ! I will have a second look... > > Regards, > > Hans > >> } >> >> void intel_hdmi_init(struct drm_i915_private *dev_priv, >> >
[PATCH 2/2] media: st-hva: don't use GFP_DMA
Set the DMA_MASK and stop using the GFP_DMA flag Signed-off-by: Fabien Dessenne --- drivers/media/platform/sti/hva/hva-mem.c | 2 +- drivers/media/platform/sti/hva/hva-v4l2.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/sti/hva/hva-mem.c b/drivers/media/platform/sti/hva/hva-mem.c index caf50cd..68047b6 100644 --- a/drivers/media/platform/sti/hva/hva-mem.c +++ b/drivers/media/platform/sti/hva/hva-mem.c @@ -22,7 +22,7 @@ int hva_mem_alloc(struct hva_ctx *ctx, u32 size, const char *name, return -ENOMEM; } - base = dma_alloc_attrs(dev, size, &paddr, GFP_KERNEL | GFP_DMA, + base = dma_alloc_attrs(dev, size, &paddr, GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); if (!base) { dev_err(dev, "%s %s : dma_alloc_attrs failed for %s (size=%d)\n", diff --git a/drivers/media/platform/sti/hva/hva-v4l2.c b/drivers/media/platform/sti/hva/hva-v4l2.c index 2ab0b5c..15080cb 100644 --- a/drivers/media/platform/sti/hva/hva-v4l2.c +++ b/drivers/media/platform/sti/hva/hva-v4l2.c @@ -1355,6 +1355,10 @@ static int hva_probe(struct platform_device *pdev) goto err; } + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + hva->dev = dev; hva->pdev = pdev; platform_set_drvdata(pdev, hva); -- 2.7.4
[PATCH 1/2] media: bdisp: don't use GFP_DMA
Set the DMA_MASK and stop using the GFP_DMA flag Signed-off-by: Fabien Dessenne --- drivers/media/platform/sti/bdisp/bdisp-hw.c | 2 +- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/sti/bdisp/bdisp-hw.c b/drivers/media/platform/sti/bdisp/bdisp-hw.c index a5eb592..26d9fa7 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-hw.c +++ b/drivers/media/platform/sti/bdisp/bdisp-hw.c @@ -455,7 +455,7 @@ int bdisp_hw_alloc_nodes(struct bdisp_ctx *ctx) /* Allocate all the nodes within a single memory page */ base = dma_alloc_attrs(dev, node_size * MAX_NB_NODE, &paddr, - GFP_KERNEL | GFP_DMA, DMA_ATTR_WRITE_COMBINE); + GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); if (!base) { dev_err(dev, "%s no mem\n", __func__); return -ENOMEM; diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index bf4ca16..66b6409 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -1297,6 +1297,10 @@ static int bdisp_probe(struct platform_device *pdev) if (!bdisp) return -ENOMEM; + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + bdisp->pdev = pdev; bdisp->dev = dev; platform_set_drvdata(pdev, bdisp); -- 2.7.4
Re: [PATCH v2 0/2] Fix potential buffer overrun root cause
On Fri, May 11, 2018 at 04:41:24PM +0200, Niklas Söderlund wrote: > Hi, > > Commit 015060cb7795eac3 ("media: rcar-vin: enable field toggle after a > set number of lines for Gen3") was an attempt to fix the issue of > writing outside the capture buffer for VIN Gen3. Unfortunately it only > fixed a symptom of a problem to such a degree I could no longer > reproduce it. > > Jacopo on the other hand working on a different setup still ran into the > issue. And he even figured out the root cause of the issue. When I > submitted the original VIN Gen3 support I had when addressing a review > comment missed to keep the crop and compose dimensions in sync with the > requested format resulting in the DMA engine not properly stopping > before writing outside the buffer. > > This series reverts the incorrect fix in 1/2 and applies a correct one > in 2/2. I think this should be picked up for v4.18. > > * Changes since v1 > - Add commit message to 1/2. > > Niklas Söderlund (2): > Revert "media: rcar-vin: enable field toggle after a set number of > lines for Gen3" > rcar-vin: fix crop and compose handling for Gen3 Reviewed-by: Simon Horman
Re: [PATCH] media: dvb-frontends: add Socionext SC1501A ISDB-S/T demodulator driver
Hi Katsuhiro, I love your patch! Yet something to improve: [auto build test ERROR on linuxtv-media/master] [also build test ERROR on v4.17-rc5 next-20180514] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Katsuhiro-Suzuki/media-dvb-frontends-add-Socionext-SC1501A-ISDB-S-T-demodulator-driver/20180515-091453 base: git://linuxtv.org/media_tree.git master config: i386-allyesconfig (attached as .config) compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/media/dvb-frontends/sc1501a.o: In function `sc1501a_set_frontend': >> sc1501a.c:(.text+0xbe0): undefined reference to `__divdi3' sc1501a.c:(.text+0xc01): undefined reference to `__divdi3' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH v2 10/29] venus: hfi_venus: add suspend functionality for Venus 4xx
This adds suspend (power collapse) functionality by reusing the suspend function for Venus 3xx and also enables idle indicator property for Venus 4xx (where it is disabled by default). Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi_venus.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index 284da69eb81b..109116e1545d 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -878,6 +878,14 @@ static int venus_sys_set_default_properties(struct venus_hfi_device *hdev) if (ret) dev_warn(dev, "setting fw debug msg ON failed (%d)\n", ret); + /* +* Idle indicator is disabled by default on some 4xx firmware versions, +* enable it explicitly in order to make suspend functional by checking +* WFI (wait-for-interrupt) bit. +*/ + if (IS_V4(hdev->core)) + venus_sys_idle_indicator = true; + ret = venus_sys_set_idle_message(hdev, venus_sys_idle_indicator); if (ret) dev_warn(dev, "setting idle response ON failed (%d)\n", ret); @@ -1525,7 +1533,8 @@ static int venus_suspend_3xx(struct venus_core *core) static int venus_suspend(struct venus_core *core) { - if (core->res->hfi_version == HFI_VERSION_3XX) + if (core->res->hfi_version == HFI_VERSION_3XX || + core->res->hfi_version == HFI_VERSION_4XX) return venus_suspend_3xx(core); return venus_suspend_1xx(core); -- 2.14.1
[PATCH v2 27/29] venus: implementing multi-stream support
This is implementing a multi-stream decoder support. The multi stream gives an option to use the secondary decoder output with different raw format (or the same in case of crop). Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/core.h| 1 + drivers/media/platform/qcom/venus/helpers.c | 204 +++- drivers/media/platform/qcom/venus/helpers.h | 6 + drivers/media/platform/qcom/venus/vdec.c| 91 - drivers/media/platform/qcom/venus/venc.c| 1 + 5 files changed, 299 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 4d6c05f156c4..85e66e2dd672 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -259,6 +259,7 @@ struct venus_inst { struct list_head list; struct mutex lock; struct venus_core *core; + struct list_head dpbbufs; struct list_head internalbufs; struct list_head registeredbufs; struct list_head delayed_process; diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index ed569705ecac..87dcf9973e6f 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -85,6 +85,112 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt) } EXPORT_SYMBOL_GPL(venus_helper_check_codec); +static int venus_helper_queue_dpb_bufs(struct venus_inst *inst) +{ + struct intbuf *buf; + int ret = 0; + + if (list_empty(&inst->dpbbufs)) + return 0; + + list_for_each_entry(buf, &inst->dpbbufs, list) { + struct hfi_frame_data fdata; + + memset(&fdata, 0, sizeof(fdata)); + fdata.alloc_len = buf->size; + fdata.device_addr = buf->da; + fdata.buffer_type = buf->type; + + ret = hfi_session_process_buf(inst, &fdata); + if (ret) + goto fail; + } + +fail: + return ret; +} + +int venus_helper_free_dpb_bufs(struct venus_inst *inst) +{ + struct intbuf *buf, *n; + + if (list_empty(&inst->dpbbufs)) + return 0; + + list_for_each_entry_safe(buf, n, &inst->dpbbufs, list) { + list_del_init(&buf->list); + dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, + buf->attrs); + kfree(buf); + } + + INIT_LIST_HEAD(&inst->dpbbufs); + + return 0; +} +EXPORT_SYMBOL_GPL(venus_helper_free_dpb_bufs); + +int venus_helper_alloc_dpb_bufs(struct venus_inst *inst) +{ + struct venus_core *core = inst->core; + struct device *dev = core->dev; + enum hfi_version ver = core->res->hfi_version; + struct hfi_buffer_requirements bufreq; + u32 buftype = inst->dpb_buftype; + unsigned int dpb_size = 0; + struct intbuf *buf; + unsigned int i; + u32 count; + int ret; + + /* no need to allocate dpb buffers */ + if (!inst->dpb_fmt) + return 0; + + if (inst->dpb_buftype == HFI_BUFFER_OUTPUT) + dpb_size = inst->output_buf_size; + else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2) + dpb_size = inst->output2_buf_size; + + if (!dpb_size) + return 0; + + ret = venus_helper_get_bufreq(inst, buftype, &bufreq); + if (ret) + return ret; + + count = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); + + for (i = 0; i < count; i++) { + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) { + ret = -ENOMEM; + goto fail; + } + + buf->type = buftype; + buf->size = dpb_size; + buf->attrs = DMA_ATTR_WRITE_COMBINE | +DMA_ATTR_NO_KERNEL_MAPPING; + buf->va = dma_alloc_attrs(dev, buf->size, &buf->da, GFP_KERNEL, + buf->attrs); + if (!buf->va) { + kfree(buf); + ret = -ENOMEM; + goto fail; + } + + list_add_tail(&buf->list, &inst->dpbbufs); + } + + return 0; + +fail: + venus_helper_free_dpb_bufs(inst); + return ret; +} +EXPORT_SYMBOL_GPL(venus_helper_alloc_dpb_bufs); + static int intbufs_set_buffer(struct venus_inst *inst, u32 type) { struct venus_core *core = inst->core; @@ -342,7 +448,10 @@ session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len) fdata.flags |= HFI_BUFFERFLAG_EOS; } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - fdata.buffer_type = HFI_BUFFER_OUTPUT; +
[PATCH v2 29/29] venus: add HEVC codec support
This add HEVC codec support for venus versions 3xx and 4xx. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/core.h| 2 ++ drivers/media/platform/qcom/venus/helpers.c | 3 ++ drivers/media/platform/qcom/venus/hfi.c | 2 ++ drivers/media/platform/qcom/venus/vdec.c| 4 +++ drivers/media/platform/qcom/venus/venc.c| 49 + 5 files changed, 60 insertions(+) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 85e66e2dd672..2a956d1b9bd1 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -185,10 +185,12 @@ struct venc_controls { u32 mpeg4; u32 h264; u32 vpx; + u32 hevc; } profile; struct { u32 mpeg4; u32 h264; + u32 hevc; } level; }; diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 87dcf9973e6f..fecadba039cf 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -71,6 +71,9 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt) case V4L2_PIX_FMT_XVID: codec = HFI_VIDEO_CODEC_DIVX; break; + case V4L2_PIX_FMT_HEVC: + codec = HFI_VIDEO_CODEC_HEVC; + break; default: return false; } diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c index 94ca27b0bb99..24207829982f 100644 --- a/drivers/media/platform/qcom/venus/hfi.c +++ b/drivers/media/platform/qcom/venus/hfi.c @@ -49,6 +49,8 @@ static u32 to_codec_type(u32 pixfmt) return HFI_VIDEO_CODEC_VP9; case V4L2_PIX_FMT_XVID: return HFI_VIDEO_CODEC_DIVX; + case V4L2_PIX_FMT_HEVC: + return HFI_VIDEO_CODEC_HEVC; default: return 0; } diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index d2d082009686..d2ffd9bd44de 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -77,6 +77,10 @@ static const struct venus_format vdec_formats[] = { .pixfmt = V4L2_PIX_FMT_XVID, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, { + .pixfmt = V4L2_PIX_FMT_HEVC, + .num_planes = 1, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, }, }; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index a703bce78abc..50a04cb1cc22 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -59,6 +59,10 @@ static const struct venus_format venc_formats[] = { .pixfmt = V4L2_PIX_FMT_VP8, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + }, { + .pixfmt = V4L2_PIX_FMT_HEVC, + .num_planes = 1, + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, }, }; @@ -220,6 +224,46 @@ static int venc_v4l2_to_hfi(int id, int value) case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY: return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY; } + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + switch (value) { + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: + default: + return HFI_HEVC_PROFILE_MAIN; + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE: + return HFI_HEVC_PROFILE_MAIN_STILL_PIC; + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10: + return HFI_HEVC_PROFILE_MAIN10; + } + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + switch (value) { + case V4L2_MPEG_VIDEO_HEVC_LEVEL_1: + default: + return HFI_HEVC_LEVEL_1; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_2: + return HFI_HEVC_LEVEL_2; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1: + return HFI_HEVC_LEVEL_21; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_3: + return HFI_HEVC_LEVEL_3; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1: + return HFI_HEVC_LEVEL_31; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_4: + return HFI_HEVC_LEVEL_4; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1: + return HFI_HEVC_LEVEL_41; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_5: + return HFI_HEVC_LEVEL_5; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1: +
[PATCH v2 28/29] venus: add sdm845 compatible and resource data
This adds sdm845 DT compatible string with it's resource data table. Reviewed-by: Rob Herring Signed-off-by: Stanimir Varbanov --- .../devicetree/bindings/media/qcom,venus.txt | 1 + drivers/media/platform/qcom/venus/core.c | 22 ++ 2 files changed, 23 insertions(+) diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt index 2693449daf73..00d0d1bf7647 100644 --- a/Documentation/devicetree/bindings/media/qcom,venus.txt +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt @@ -6,6 +6,7 @@ Definition: Value should contain one of: - "qcom,msm8916-venus" - "qcom,msm8996-venus" + - "qcom,sdm845-venus" - reg: Usage: required Value type: diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 381bfdd688db..bb6add9d340e 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -450,9 +450,31 @@ static const struct venus_resources msm8996_res = { .fwname = "qcom/venus-4.2/venus.mdt", }; +static const struct freq_tbl sdm845_freq_table[] = { + { 1944000, 38000 }, /* 4k UHD @ 60 */ + { 972000, 32000 }, /* 4k UHD @ 30 */ + { 489600, 2 }, /* 1080p @ 60 */ + { 244800, 1 }, /* 1080p @ 30 */ +}; + +static const struct venus_resources sdm845_res = { + .freq_tbl = sdm845_freq_table, + .freq_tbl_size = ARRAY_SIZE(sdm845_freq_table), + .clks = {"core", "iface", "bus" }, + .clks_num = 3, + .max_load = 2563200, + .hfi_version = HFI_VERSION_4XX, + .vmem_id = VIDC_RESOURCE_NONE, + .vmem_size = 0, + .vmem_addr = 0, + .dma_mask = 0xe000 - 1, + .fwname = "qcom/venus-5.2/venus.mdt", +}; + static const struct of_device_id venus_dt_match[] = { { .compatible = "qcom,msm8916-venus", .data = &msm8916_res, }, { .compatible = "qcom,msm8996-venus", .data = &msm8996_res, }, + { .compatible = "qcom,sdm845-venus", .data = &sdm845_res, }, { } }; MODULE_DEVICE_TABLE(of, venus_dt_match); -- 2.14.1
[PATCH v2 25/29] venus: vdec: new function for output configuration
Make a new function vdec_output_conf() for decoder output configuration. vdec_output_conf() will set properties via HFI interface related to the output configuration, and keep vdec_set_properties() which will set properties related to decoding parameters. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/vdec.c | 35 ++-- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 5a5e3e2fece4..3a699af0ab58 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -545,6 +545,23 @@ static const struct v4l2_ioctl_ops vdec_ioctl_ops = { static int vdec_set_properties(struct venus_inst *inst) { struct vdec_controls *ctr = &inst->controls.dec; + struct hfi_enable en = { .enable = 1 }; + u32 ptype; + int ret; + + if (ctr->post_loop_deb_mode) { + ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER; + en.enable = 1; + ret = hfi_session_set_property(inst, ptype, &en); + if (ret) + return ret; + } + + return 0; +} + +static int vdec_output_conf(struct venus_inst *inst) +{ struct venus_core *core = inst->core; struct hfi_enable en = { .enable = 1 }; u32 ptype; @@ -569,14 +586,6 @@ static int vdec_set_properties(struct venus_inst *inst) if (ret) return ret; - if (ctr->post_loop_deb_mode) { - ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER; - en.enable = 1; - ret = hfi_session_set_property(inst, ptype, &en); - if (ret) - return ret; - } - return 0; } @@ -724,7 +733,6 @@ static int vdec_verify_conf(struct venus_inst *inst) static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) { struct venus_inst *inst = vb2_get_drv_priv(q); - struct venus_core *core = inst->core; int ret; mutex_lock(&inst->lock); @@ -753,12 +761,9 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) if (ret) goto deinit_sess; - if (core->res->hfi_version == HFI_VERSION_3XX) { - ret = venus_helper_set_bufsize(inst, inst->output_buf_size, - HFI_BUFFER_OUTPUT); - if (ret) - goto deinit_sess; - } + ret = vdec_output_conf(inst); + if (ret) + goto deinit_sess; ret = vdec_verify_conf(inst); if (ret) -- 2.14.1
[PATCH v2 26/29] venus: move frame size calculations in common place
move calculations of raw and compressed in a common helper and make it identical for encoder and decoder. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 98 + drivers/media/platform/qcom/venus/helpers.h | 2 + drivers/media/platform/qcom/venus/vdec.c| 54 drivers/media/platform/qcom/venus/venc.c| 56 - 4 files changed, 126 insertions(+), 84 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index f0a0fca60c76..ed569705ecac 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -455,6 +455,104 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, } EXPORT_SYMBOL_GPL(venus_helper_get_bufreq); +static u32 get_framesize_raw_nv12(u32 width, u32 height) +{ + u32 y_stride, uv_stride, y_plane; + u32 y_sclines, uv_sclines, uv_plane; + u32 size; + + y_stride = ALIGN(width, 128); + uv_stride = ALIGN(width, 128); + y_sclines = ALIGN(height, 32); + uv_sclines = ALIGN(((height + 1) >> 1), 16); + + y_plane = y_stride * y_sclines; + uv_plane = uv_stride * uv_sclines + SZ_4K; + size = y_plane + uv_plane + SZ_8K; + + return ALIGN(size, SZ_4K); +} + +static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height) +{ + u32 y_meta_stride, y_meta_plane; + u32 y_stride, y_plane; + u32 uv_meta_stride, uv_meta_plane; + u32 uv_stride, uv_plane; + u32 extradata = SZ_16K; + + y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64); + y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(height, 8), 16); + y_meta_plane = ALIGN(y_meta_plane, SZ_4K); + + y_stride = ALIGN(width, 128); + y_plane = ALIGN(y_stride * ALIGN(height, 32), SZ_4K); + + uv_meta_stride = ALIGN(DIV_ROUND_UP(width / 2, 16), 64); + uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(height / 2, 8), 16); + uv_meta_plane = ALIGN(uv_meta_plane, SZ_4K); + + uv_stride = ALIGN(width, 128); + uv_plane = ALIGN(uv_stride * ALIGN(height / 2, 32), SZ_4K); + + return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane + +max(extradata, y_stride * 48), SZ_4K); +} + +u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height) +{ + switch (hfi_fmt) { + case HFI_COLOR_FORMAT_NV12: + case HFI_COLOR_FORMAT_NV21: + return get_framesize_raw_nv12(width, height); + case HFI_COLOR_FORMAT_NV12_UBWC: + return get_framesize_raw_nv12_ubwc(width, height); + default: + return 0; + } +} +EXPORT_SYMBOL_GPL(venus_helper_get_framesz_raw); + +u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height) +{ + u32 hfi_fmt, sz; + bool compressed; + + switch (v4l2_fmt) { + case V4L2_PIX_FMT_MPEG: + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H264_NO_SC: + case V4L2_PIX_FMT_H264_MVC: + case V4L2_PIX_FMT_H263: + case V4L2_PIX_FMT_MPEG1: + case V4L2_PIX_FMT_MPEG2: + case V4L2_PIX_FMT_MPEG4: + case V4L2_PIX_FMT_XVID: + case V4L2_PIX_FMT_VC1_ANNEX_G: + case V4L2_PIX_FMT_VC1_ANNEX_L: + case V4L2_PIX_FMT_VP8: + case V4L2_PIX_FMT_VP9: + case V4L2_PIX_FMT_HEVC: + compressed = true; + break; + default: + compressed = false; + break; + } + + if (compressed) { + sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2; + return ALIGN(sz, SZ_4K); + } + + hfi_fmt = to_hfi_raw_fmt(v4l2_fmt); + if (!hfi_fmt) + return 0; + + return venus_helper_get_framesz_raw(hfi_fmt, width, height); +} +EXPORT_SYMBOL_GPL(venus_helper_get_framesz); + int venus_helper_set_input_resolution(struct venus_inst *inst, unsigned int width, unsigned int height) { diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 92be45894a69..92b167a47166 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -33,6 +33,8 @@ void venus_helper_m2m_device_run(void *priv); void venus_helper_m2m_job_abort(void *priv); int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, struct hfi_buffer_requirements *req); +u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height); +u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height); int venus_helper_set_input_resolution(struct venus_inst *inst, unsigned int width, unsigned int height); int venus_helper_set_output_resolution(struct venus_inst *inst, diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/
[PATCH v2 17/29] venus: add helper function to set actual buffer size
Add and use a helper function to set actual buffer size for particular buffer type. This is also preparation to use the second decoder output. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 12 drivers/media/platform/qcom/venus/helpers.h | 1 + drivers/media/platform/qcom/venus/vdec.c| 10 ++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 824ad4d2d064..94664a3ce3e2 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -544,6 +544,18 @@ int venus_helper_set_dyn_bufmode(struct venus_inst *inst) } EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode); +int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype) +{ + u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; + struct hfi_buffer_size_actual bufsz; + + bufsz.type = buftype; + bufsz.size = bufsize; + + return hfi_session_set_property(inst, ptype, &bufsz); +} +EXPORT_SYMBOL_GPL(venus_helper_set_bufsize); + static void delayed_process_buf_func(struct work_struct *work) { struct venus_buffer *buf, *n; diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 52b961ed491e..cd306bd8978f 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -41,6 +41,7 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, unsigned int output_bufs); int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt); int venus_helper_set_dyn_bufmode(struct venus_inst *inst); +int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype); void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf); void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx); void venus_helper_init_instance(struct venus_inst *inst); diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 271192273953..e8e00d0650e9 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -710,7 +710,6 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) { struct venus_inst *inst = vb2_get_drv_priv(q); struct venus_core *core = inst->core; - u32 ptype; int ret; mutex_lock(&inst->lock); @@ -740,13 +739,8 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) goto deinit_sess; if (core->res->hfi_version == HFI_VERSION_3XX) { - struct hfi_buffer_size_actual buf_sz; - - ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; - buf_sz.type = HFI_BUFFER_OUTPUT; - buf_sz.size = inst->output_buf_size; - - ret = hfi_session_set_property(inst, ptype, &buf_sz); + ret = venus_helper_set_bufsize(inst, inst->output_buf_size, + HFI_BUFFER_OUTPUT); if (ret) goto deinit_sess; } -- 2.14.1
[PATCH v2 24/29] venus: vdec: get required input buffers as well
Rework and rename vdec_cap_num_buffers() to get the number of input buffers too. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/vdec.c | 41 +++- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 898c5edb91f5..5a5e3e2fece4 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -603,19 +603,32 @@ static int vdec_init_session(struct venus_inst *inst) return ret; } -static int vdec_cap_num_buffers(struct venus_inst *inst, unsigned int *num) +static int vdec_num_buffers(struct venus_inst *inst, unsigned int *in_num, + unsigned int *out_num) { + enum hfi_version ver = inst->core->res->hfi_version; struct hfi_buffer_requirements bufreq; int ret; + *in_num = *out_num = 0; + ret = vdec_init_session(inst); if (ret) return ret; + ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); + if (ret) + goto deinit; + + *in_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); + ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); + if (ret) + goto deinit; - *num = bufreq.count_actual; + *out_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); +deinit: hfi_session_deinit(inst); return ret; @@ -626,7 +639,7 @@ static int vdec_queue_setup(struct vb2_queue *q, unsigned int sizes[], struct device *alloc_devs[]) { struct venus_inst *inst = vb2_get_drv_priv(q); - unsigned int p, num; + unsigned int p, in_num, out_num; int ret = 0; if (*num_planes) { @@ -649,35 +662,29 @@ static int vdec_queue_setup(struct vb2_queue *q, return 0; } + ret = vdec_num_buffers(inst, &in_num, &out_num); + if (ret) + return ret; + switch (q->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: *num_planes = inst->fmt_out->num_planes; sizes[0] = get_framesize_compressed(inst->out_width, inst->out_height); inst->input_buf_size = sizes[0]; + *num_buffers = max(*num_buffers, in_num); inst->num_input_bufs = *num_buffers; - - ret = vdec_cap_num_buffers(inst, &num); - if (ret) - break; - - inst->num_output_bufs = num; + inst->num_output_bufs = out_num; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: *num_planes = inst->fmt_cap->num_planes; - ret = vdec_cap_num_buffers(inst, &num); - if (ret) - break; - - *num_buffers = max(*num_buffers, num); - for (p = 0; p < *num_planes; p++) sizes[p] = get_framesize_uncompressed(p, inst->width, inst->height); - - inst->num_output_bufs = *num_buffers; inst->output_buf_size = sizes[0]; + *num_buffers = max(*num_buffers, out_num); + inst->num_output_bufs = *num_buffers; break; default: ret = -EINVAL; -- 2.14.1
[PATCH v2 23/29] venus: helpers: add a helper to return opb buffer sizes
Add a helper function to return current output picture buffer size. OPB sizes can vary depending on the selected decoder output(s). Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/core.h| 10 ++ drivers/media/platform/qcom/venus/helpers.c | 15 +++ drivers/media/platform/qcom/venus/helpers.h | 1 + 3 files changed, 26 insertions(+) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 255292899204..4d6c05f156c4 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -234,6 +234,11 @@ struct venus_buffer { * @num_output_bufs: holds number of output buffers * @input_buf_size holds input buffer size * @output_buf_size: holds output buffer size + * @output2_buf_size: holds secondary decoder output buffer size + * @dpb_buftype: decoded picture buffer type + * @dpb_fmt: decodec picture buffre raw format + * @opb_buftype: output picture buffer type + * @opb_fmt: output picture buffer raw format * @reconfig: a flag raised by decoder when the stream resolution changed * @reconfig_width:holds the new width * @reconfig_height: holds the new height @@ -282,6 +287,11 @@ struct venus_inst { unsigned int num_output_bufs; unsigned int input_buf_size; unsigned int output_buf_size; + unsigned int output2_buf_size; + u32 dpb_buftype; + u32 dpb_fmt; + u32 opb_buftype; + u32 opb_fmt; bool reconfig; u32 reconfig_width; u32 reconfig_height; diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index f04d16953b3a..f0a0fca60c76 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -611,6 +611,21 @@ int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype) } EXPORT_SYMBOL_GPL(venus_helper_set_bufsize); +unsigned int venus_helper_get_opb_size(struct venus_inst *inst) +{ + /* the encoder has only one output */ + if (inst->session_type == VIDC_SESSION_TYPE_ENC) + return inst->output_buf_size; + + if (inst->opb_buftype == HFI_BUFFER_OUTPUT) + return inst->output_buf_size; + else if (inst->opb_buftype == HFI_BUFFER_OUTPUT2) + return inst->output2_buf_size; + + return 0; +} +EXPORT_SYMBOL_GPL(venus_helper_get_opb_size); + static void delayed_process_buf_func(struct work_struct *work) { struct venus_buffer *buf, *n; diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 8ff4bd3ef958..92be45894a69 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -48,6 +48,7 @@ int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format, int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt); int venus_helper_set_dyn_bufmode(struct venus_inst *inst); int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype); +unsigned int venus_helper_get_opb_size(struct venus_inst *inst); void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf); void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx); void venus_helper_init_instance(struct venus_inst *inst); -- 2.14.1
[PATCH v2 14/29] venus: core: delete not used flag for buffer mode
Delete not used flag for capture buffer allocation mode. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/core.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index fe2d2b9e8af8..c46334454cd9 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -249,7 +249,6 @@ struct venus_buffer { * @priv: a private for HFI operations callbacks * @session_type: the type of the session (decoder or encoder) * @hprop: a union used as a holder by get property - * @cap_bufs_mode_static: buffers allocation mode capability * @cap_bufs_mode_dynamic: buffers allocation mode capability */ struct venus_inst { @@ -299,7 +298,6 @@ struct venus_inst { const struct hfi_inst_ops *ops; u32 session_type; union hfi_get_property hprop; - bool cap_bufs_mode_static; bool cap_bufs_mode_dynamic; }; -- 2.14.1
[PATCH v2 21/29] venus: helpers,vdec,venc: add helpers to set work mode and core usage
These are new properties applicable to Venus version 4xx. Add the helpers and call them from decoder and encoder drivers. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 28 drivers/media/platform/qcom/venus/helpers.h | 2 ++ drivers/media/platform/qcom/venus/vdec.c| 8 drivers/media/platform/qcom/venus/venc.c| 8 4 files changed, 46 insertions(+) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 0d55604f7484..adf8701a64bb 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -484,6 +484,34 @@ int venus_helper_set_output_resolution(struct venus_inst *inst, } EXPORT_SYMBOL_GPL(venus_helper_set_output_resolution); +int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode) +{ + u32 ptype = HFI_PROPERTY_PARAM_WORK_MODE; + struct hfi_video_work_mode wm; + + if (!IS_V4(inst->core)) + return 0; + + wm.video_work_mode = mode; + + return hfi_session_set_property(inst, ptype, &wm); +} +EXPORT_SYMBOL_GPL(venus_helper_set_work_mode); + +int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage) +{ + u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE; + struct hfi_videocores_usage_type cu; + + if (!IS_V4(inst->core)) + return 0; + + cu.video_core_enable_mask = usage; + + return hfi_session_set_property(inst, ptype, &cu); +} +EXPORT_SYMBOL_GPL(venus_helper_set_core_usage); + int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, unsigned int output_bufs) { diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 79af7845efbd..d5e727e1ecab 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -38,6 +38,8 @@ int venus_helper_set_input_resolution(struct venus_inst *inst, int venus_helper_set_output_resolution(struct venus_inst *inst, unsigned int width, unsigned int height, u32 buftype); +int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode); +int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage); int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, unsigned int output_bufs); int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format, diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index e8e00d0650e9..3c7ffebe4bad 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -550,6 +550,14 @@ static int vdec_set_properties(struct venus_inst *inst) u32 ptype; int ret; + ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2); + if (ret) + return ret; + + ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_1); + if (ret) + return ret; + if (core->res->hfi_version == HFI_VERSION_1XX) { ptype = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER; ret = hfi_session_set_property(inst, ptype, &en); diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 8970f14b3a82..3b3299bff1cd 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -643,6 +643,14 @@ static int venc_set_properties(struct venus_inst *inst) u32 ptype, rate_control, bitrate, profile = 0, level = 0; int ret; + ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2); + if (ret) + return ret; + + ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_2); + if (ret) + return ret; + ptype = HFI_PROPERTY_CONFIG_FRAME_RATE; frate.buffer_type = HFI_BUFFER_OUTPUT; frate.framerate = inst->fps * (1 << 16); -- 2.14.1
[PATCH v2 22/29] venus: helpers: extend set_num_bufs helper with one more argument
Extend venus_helper_set_num_bufs() helper function with one more argument to set number of output buffers for the secondary decoder output. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 16 ++-- drivers/media/platform/qcom/venus/helpers.h | 3 ++- drivers/media/platform/qcom/venus/vdec.c| 2 +- drivers/media/platform/qcom/venus/venc.c| 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index adf8701a64bb..f04d16953b3a 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -513,7 +513,8 @@ int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage) EXPORT_SYMBOL_GPL(venus_helper_set_core_usage); int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, - unsigned int output_bufs) + unsigned int output_bufs, + unsigned int output2_bufs) { u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL; struct hfi_buffer_count_actual buf_count; @@ -529,7 +530,18 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, buf_count.type = HFI_BUFFER_OUTPUT; buf_count.count_actual = output_bufs; - return hfi_session_set_property(inst, ptype, &buf_count); + ret = hfi_session_set_property(inst, ptype, &buf_count); + if (ret) + return ret; + + if (output2_bufs) { + buf_count.type = HFI_BUFFER_OUTPUT2; + buf_count.count_actual = output2_bufs; + + ret = hfi_session_set_property(inst, ptype, &buf_count); + } + + return ret; } EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs); diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index d5e727e1ecab..8ff4bd3ef958 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -41,7 +41,8 @@ int venus_helper_set_output_resolution(struct venus_inst *inst, int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode); int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage); int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, - unsigned int output_bufs); + unsigned int output_bufs, + unsigned int output2_bufs); int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format, u32 buftype); int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt); diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 3c7ffebe4bad..898c5edb91f5 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -758,7 +758,7 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) goto deinit_sess; ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, - VB2_MAX_FRAME); + VB2_MAX_FRAME, VB2_MAX_FRAME); if (ret) goto deinit_sess; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 3b3299bff1cd..c9c40d1ce7c6 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -963,7 +963,7 @@ static int venc_start_streaming(struct vb2_queue *q, unsigned int count) goto deinit_sess; ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, - inst->num_output_bufs); + inst->num_output_bufs, 0); if (ret) goto deinit_sess; -- 2.14.1
[PATCH v2 16/29] venus: add a helper function to set dynamic buffer mode
Adds a new helper function to set dynamic buffer mode if it is supported by current HFI version. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 22 ++ drivers/media/platform/qcom/venus/helpers.h | 1 + drivers/media/platform/qcom/venus/vdec.c| 15 +++ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 1eda19adbf28..824ad4d2d064 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -522,6 +522,28 @@ int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt) } EXPORT_SYMBOL_GPL(venus_helper_set_color_format); +int venus_helper_set_dyn_bufmode(struct venus_inst *inst) +{ + u32 ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE; + struct hfi_buffer_alloc_mode mode; + int ret; + + if (!is_dynamic_bufmode(inst)) + return 0; + + mode.type = HFI_BUFFER_OUTPUT; + mode.mode = HFI_BUFFER_MODE_DYNAMIC; + + ret = hfi_session_set_property(inst, ptype, &mode); + if (ret) + return ret; + + mode.type = HFI_BUFFER_OUTPUT2; + + return hfi_session_set_property(inst, ptype, &mode); +} +EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode); + static void delayed_process_buf_func(struct work_struct *work) { struct venus_buffer *buf, *n; diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 0e64aa95624a..52b961ed491e 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -40,6 +40,7 @@ int venus_helper_set_output_resolution(struct venus_inst *inst, int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, unsigned int output_bufs); int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt); +int venus_helper_set_dyn_bufmode(struct venus_inst *inst); void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf); void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx); void venus_helper_init_instance(struct venus_inst *inst); diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 2bd81de6328a..271192273953 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -557,18 +557,9 @@ static int vdec_set_properties(struct venus_inst *inst) return ret; } - if (core->res->hfi_version == HFI_VERSION_3XX || - inst->cap_bufs_mode_dynamic) { - struct hfi_buffer_alloc_mode mode; - - ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE; - mode.type = HFI_BUFFER_OUTPUT; - mode.mode = HFI_BUFFER_MODE_DYNAMIC; - - ret = hfi_session_set_property(inst, ptype, &mode); - if (ret) - return ret; - } + ret = venus_helper_set_dyn_bufmode(inst); + if (ret) + return ret; if (ctr->post_loop_deb_mode) { ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER; -- 2.14.1
[PATCH v2 15/29] venus: helpers: rename a helper function and use buffer mode from caps
Rename is_reg_unreg_needed() to better name is_dynamic_bufmode() and use buffer mode from enumerated per codec capabilities. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 2b21f6ed7502..1eda19adbf28 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -354,18 +354,19 @@ session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) return 0; } -static inline int is_reg_unreg_needed(struct venus_inst *inst) +static inline int is_dynamic_bufmode(struct venus_inst *inst) { - if (inst->session_type == VIDC_SESSION_TYPE_DEC && - inst->core->res->hfi_version == HFI_VERSION_3XX) - return 0; + struct venus_core *core = inst->core; + struct venus_caps *caps; - if (inst->session_type == VIDC_SESSION_TYPE_DEC && - inst->cap_bufs_mode_dynamic && - inst->core->res->hfi_version == HFI_VERSION_1XX) + caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type); + if (!caps) return 0; - return 1; + if (caps->cap_bufs_mode_dynamic) + return 1; + + return 0; } static int session_unregister_bufs(struct venus_inst *inst) @@ -374,7 +375,7 @@ static int session_unregister_bufs(struct venus_inst *inst) struct hfi_buffer_desc bd; int ret = 0; - if (!is_reg_unreg_needed(inst)) + if (is_dynamic_bufmode(inst)) return 0; list_for_each_entry_safe(buf, n, &inst->registeredbufs, reg_list) { @@ -394,7 +395,7 @@ static int session_register_bufs(struct venus_inst *inst) struct venus_buffer *buf; int ret = 0; - if (!is_reg_unreg_needed(inst)) + if (is_dynamic_bufmode(inst)) return 0; list_for_each_entry(buf, &inst->registeredbufs, reg_list) { -- 2.14.1
Re: [PATCH v11] media: imx258: Add imx258 camera sensor driver
On Tue, May 15, 2018 at 03:46:37AM +, Zheng, Jian Xu wrote: > Hi Sakari, > > > -Original Message- > > From: linux-media-ow...@vger.kernel.org [mailto:linux-media- > > ow...@vger.kernel.org] On Behalf Of Sakari Ailus > > Sent: Saturday, May 12, 2018 8:48 PM > > To: Zheng, Jian Xu > > Cc: Chen, JasonX Z ; Tomasz Figa > > ; Yeh, Andy ; Linux Media > > Mailing List ; Chiang, AlanX > > ; Qiu, Tian Shu > > Subject: Re: [PATCH v11] media: imx258: Add imx258 camera sensor driver > > > > On Thu, May 10, 2018 at 11:08:43AM +, Zheng, Jian Xu wrote: > > > Hi Sakari & Jason, > > > > > > > -Original Message- > > > > From: linux-media-ow...@vger.kernel.org [mailto:linux-media- > > > > ow...@vger.kernel.org] On Behalf Of Sakari Ailus > > > > Sent: Wednesday, May 9, 2018 5:43 PM > > > > To: Chen, JasonX Z > > > > Cc: Tomasz Figa ; Yeh, Andy > > > > ; Linux Media Mailing List > > > > ; Chiang, AlanX > > > > > > > > Subject: Re: [PATCH v11] media: imx258: Add imx258 camera sensor > > > > driver > > > > > > > > Hi Jason, > > > > > > > > On Wed, May 09, 2018 at 09:28:30AM +, Chen, JasonX Z wrote: > > > > > Hello Tomasz > > > > > > > > > > >> +/* Test Pattern Control */ > > > > > >> +#define IMX258_REG_TEST_PATTERN0x0600 > > > > > >> +#define IMX258_TEST_PATTERN_DISABLE0 > > > > > >> +#define IMX258_TEST_PATTERN_SOLID_COLOR1 > > > > > >> +#define IMX258_TEST_PATTERN_COLOR_BARS 2 #define > > > > > >> +IMX258_TEST_PATTERN_GREY_COLOR 3 > > > > > >> +#define IMX258_TEST_PATTERN_PN94 > > > > > > I suppose we only use IMX258_TEST_PATTERN_COLOR_BARS. I heard that > > > we'd better remove the functions/code no one would use. Is that true? e.g. > > > remove all h_flip and v_flip ioctls because it's not used by anyone. > > > > HFLIP and VFLIP support were AFAIR removed as they were not supported > > correctly by the driver --- they do affect the pixel order, i.e. the format. > So you mean that if the sensor is RAW format, we should not implement > HFLIP/VFLIP. Because it changes the pixel order? I don't quite follow the > logic here. In the meantime, if the logic works here, we need some other > kind of HFLIP/VFLIP ioctl because it's supported by HW. You can implement it but the implementation needs to be correctly reflect the flipping in the pixel order reported by the driver. -- Sakari Ailus sakari.ai...@linux.intel.com
[PATCH v2 20/29] venus: helpers: add a new helper to set raw format
The new helper will has one more argument for buffer type, that way the decoder can configure the format on it's secondary output. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 52 ++--- drivers/media/platform/qcom/venus/helpers.h | 2 ++ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 5512fbfdebb9..0d55604f7484 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -410,6 +410,20 @@ static int session_register_bufs(struct venus_inst *inst) return ret; } +static u32 to_hfi_raw_fmt(u32 v4l2_fmt) +{ + switch (v4l2_fmt) { + case V4L2_PIX_FMT_NV12: + return HFI_COLOR_FORMAT_NV12; + case V4L2_PIX_FMT_NV21: + return HFI_COLOR_FORMAT_NV21; + default: + break; + } + + return 0; +} + int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, struct hfi_buffer_requirements *req) { @@ -491,35 +505,35 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, } EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs); -int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt) +int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format, + u32 buftype) { - struct hfi_uncompressed_format_select fmt; u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT; - int ret; + struct hfi_uncompressed_format_select fmt; + + fmt.buffer_type = buftype; + fmt.format = hfi_format; + + return hfi_session_set_property(inst, ptype, &fmt); +} +EXPORT_SYMBOL_GPL(venus_helper_set_raw_format); + +int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt) +{ + u32 hfi_format, buftype; if (inst->session_type == VIDC_SESSION_TYPE_DEC) - fmt.buffer_type = HFI_BUFFER_OUTPUT; + buftype = HFI_BUFFER_OUTPUT; else if (inst->session_type == VIDC_SESSION_TYPE_ENC) - fmt.buffer_type = HFI_BUFFER_INPUT; + buftype = HFI_BUFFER_INPUT; else return -EINVAL; - switch (pixfmt) { - case V4L2_PIX_FMT_NV12: - fmt.format = HFI_COLOR_FORMAT_NV12; - break; - case V4L2_PIX_FMT_NV21: - fmt.format = HFI_COLOR_FORMAT_NV21; - break; - default: + hfi_format = to_hfi_raw_fmt(pixfmt); + if (!hfi_format) return -EINVAL; - } - ret = hfi_session_set_property(inst, ptype, &fmt); - if (ret) - return ret; - - return 0; + return venus_helper_set_raw_format(inst, hfi_format, buftype); } EXPORT_SYMBOL_GPL(venus_helper_set_color_format); diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 0de9989adcdb..79af7845efbd 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -40,6 +40,8 @@ int venus_helper_set_output_resolution(struct venus_inst *inst, u32 buftype); int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, unsigned int output_bufs); +int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format, + u32 buftype); int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt); int venus_helper_set_dyn_bufmode(struct venus_inst *inst); int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype); -- 2.14.1
[PATCH v2 13/29] venus: helpers: make a commmon function for power_enable
Make common function which will enable power when enabling/disabling clocks and also covers Venus 3xx/4xx versions. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 51 + drivers/media/platform/qcom/venus/helpers.h | 2 ++ drivers/media/platform/qcom/venus/vdec.c| 25 -- drivers/media/platform/qcom/venus/venc.c| 25 -- 4 files changed, 67 insertions(+), 36 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index d9065cc8a7d3..2b21f6ed7502 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -13,6 +13,7 @@ * */ #include +#include #include #include #include @@ -24,6 +25,7 @@ #include "core.h" #include "helpers.h" #include "hfi_helper.h" +#include "hfi_venus_io.h" struct intbuf { struct list_head list; @@ -781,3 +783,52 @@ void venus_helper_init_instance(struct venus_inst *inst) } } EXPORT_SYMBOL_GPL(venus_helper_init_instance); + +int venus_helper_power_enable(struct venus_core *core, u32 session_type, + bool enable) +{ + void __iomem *ctrl, *stat; + u32 val; + int ret; + + if (!IS_V3(core) && !IS_V4(core)) + return -EINVAL; + + if (IS_V3(core)) { + if (session_type == VIDC_SESSION_TYPE_DEC) + ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL; + else + ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL; + if (enable) + writel(0, ctrl); + else + writel(1, ctrl); + + return 0; + } + + if (session_type == VIDC_SESSION_TYPE_DEC) { + ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL; + stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS; + } else { + ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL; + stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS; + } + + if (enable) { + writel(0, ctrl); + + ret = readl_poll_timeout(stat, val, val & BIT(1), 1, 100); + if (ret) + return ret; + } else { + writel(1, ctrl); + + ret = readl_poll_timeout(stat, val, !(val & BIT(1)), 1, 100); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(venus_helper_power_enable); diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 971392be5df5..0e64aa95624a 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -43,4 +43,6 @@ int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt); void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf); void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx); void venus_helper_init_instance(struct venus_inst *inst); +int venus_helper_power_enable(struct venus_core *core, u32 session_type, + bool enable); #endif diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 3b38bd1241b0..2bd81de6328a 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1123,26 +1123,21 @@ static int vdec_remove(struct platform_device *pdev) static __maybe_unused int vdec_runtime_suspend(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); + int ret; if (IS_V1(core)) return 0; - if (IS_V3(core)) - writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); - else if (IS_V4(core)) - writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL); + ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true); if (IS_V4(core)) clk_disable_unprepare(core->core0_bus_clk); clk_disable_unprepare(core->core0_clk); - if (IS_V3(core)) - writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); - else if (IS_V4(core)) - writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL); + ret |= venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false); - return 0; + return ret; } static __maybe_unused int vdec_runtime_resume(struct device *dev) @@ -1153,20 +1148,14 @@ static __maybe_unused int vdec_runtime_resume(struct device *dev) if (IS_V1(core)) return 0; - if (IS_V3(core)) - writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); - else if (IS_V4(core)) - writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL); + ret = venus_helper_p
[PATCH v2 12/29] venus: add common capability parser
This adds common capability parser for all supported Venus versions. Having it will help to enumerate better the supported raw formars and codecs and also the capabilities for every codec like max/min width/height, framerate, bitrate and so on. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/Makefile | 3 +- drivers/media/platform/qcom/venus/core.c | 85 ++ drivers/media/platform/qcom/venus/core.h | 68 +++-- drivers/media/platform/qcom/venus/hfi.c| 5 +- drivers/media/platform/qcom/venus/hfi_helper.h | 28 +- drivers/media/platform/qcom/venus/hfi_msgs.c | 348 ++--- drivers/media/platform/qcom/venus/hfi_parser.c | 295 + drivers/media/platform/qcom/venus/hfi_parser.h | 45 drivers/media/platform/qcom/venus/vdec.c | 38 +-- drivers/media/platform/qcom/venus/venc.c | 52 ++-- 10 files changed, 530 insertions(+), 437 deletions(-) create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.c create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.h diff --git a/drivers/media/platform/qcom/venus/Makefile b/drivers/media/platform/qcom/venus/Makefile index bfd4edf7c83f..b44b11b03e12 100644 --- a/drivers/media/platform/qcom/venus/Makefile +++ b/drivers/media/platform/qcom/venus/Makefile @@ -2,7 +2,8 @@ # Makefile for Qualcomm Venus driver venus-core-objs += core.o helpers.o firmware.o \ - hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o + hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \ + hfi_parser.o venus-dec-objs += vdec.o vdec_ctrls.o venus-enc-objs += venc.o venc_ctrls.o diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 41eef376eb2d..381bfdd688db 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -152,6 +152,83 @@ static void venus_clks_disable(struct venus_core *core) clk_disable_unprepare(core->clks[i]); } +static u32 to_v4l2_codec_type(u32 codec) +{ + switch (codec) { + case HFI_VIDEO_CODEC_H264: + return V4L2_PIX_FMT_H264; + case HFI_VIDEO_CODEC_H263: + return V4L2_PIX_FMT_H263; + case HFI_VIDEO_CODEC_MPEG1: + return V4L2_PIX_FMT_MPEG1; + case HFI_VIDEO_CODEC_MPEG2: + return V4L2_PIX_FMT_MPEG2; + case HFI_VIDEO_CODEC_MPEG4: + return V4L2_PIX_FMT_MPEG4; + case HFI_VIDEO_CODEC_VC1: + return V4L2_PIX_FMT_VC1_ANNEX_G; + case HFI_VIDEO_CODEC_VP8: + return V4L2_PIX_FMT_VP8; + case HFI_VIDEO_CODEC_VP9: + return V4L2_PIX_FMT_VP9; + case HFI_VIDEO_CODEC_DIVX: + case HFI_VIDEO_CODEC_DIVX_311: + return V4L2_PIX_FMT_XVID; + default: + return 0; + } +} + +static int venus_enumerate_codecs(struct venus_core *core, u32 type) +{ + const struct hfi_inst_ops dummy_ops = {}; + struct venus_inst *inst; + u32 codec, codecs; + unsigned int i; + int ret; + + if (core->res->hfi_version != HFI_VERSION_1XX) + return 0; + + inst = kzalloc(sizeof(*inst), GFP_KERNEL); + if (!inst) + return -ENOMEM; + + mutex_init(&inst->lock); + inst->core = core; + inst->session_type = type; + if (type == VIDC_SESSION_TYPE_DEC) + codecs = core->dec_codecs; + else + codecs = core->enc_codecs; + + ret = hfi_session_create(inst, &dummy_ops); + if (ret) + goto err; + + for (i = 0; i < MAX_CODEC_NUM; i++) { + codec = (1 << i) & codecs; + if (!codec) + continue; + + ret = hfi_session_init(inst, to_v4l2_codec_type(codec)); + if (ret) + goto done; + + ret = hfi_session_deinit(inst); + if (ret) + goto done; + } + +done: + hfi_session_destroy(inst); +err: + mutex_destroy(&inst->lock); + kfree(inst); + + return ret; +} + static int venus_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -219,6 +296,14 @@ static int venus_probe(struct platform_device *pdev) if (ret) goto err_venus_shutdown; + ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC); + if (ret) + goto err_venus_shutdown; + + ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC); + if (ret) + goto err_venus_shutdown; + ret = v4l2_device_register(dev, &core->v4l2_dev); if (ret) goto err_core_deinit; diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index b5b9a84e9155..fe2d2b9e8af8 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/
[PATCH v2 18/29] venus: delete no longer used bufmode flag from instance
Delete no longer used flag cap_bufs_mode_dynamic from instance structure. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/core.h | 2 -- drivers/media/platform/qcom/venus/hfi_parser.c | 6 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index c46334454cd9..255292899204 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -249,7 +249,6 @@ struct venus_buffer { * @priv: a private for HFI operations callbacks * @session_type: the type of the session (decoder or encoder) * @hprop: a union used as a holder by get property - * @cap_bufs_mode_dynamic: buffers allocation mode capability */ struct venus_inst { struct list_head list; @@ -298,7 +297,6 @@ struct venus_inst { const struct hfi_inst_ops *ops; u32 session_type; union hfi_get_property hprop; - bool cap_bufs_mode_dynamic; }; #define IS_V1(core)((core)->res->hfi_version == HFI_VERSION_1XX) diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c index f9181d999b23..ad039a3444b8 100644 --- a/drivers/media/platform/qcom/venus/hfi_parser.c +++ b/drivers/media/platform/qcom/venus/hfi_parser.c @@ -75,13 +75,9 @@ static void parse_alloc_mode(struct venus_core *core, struct venus_inst *inst, while (num_entries--) { if (mode->buffer_type == HFI_BUFFER_OUTPUT || - mode->buffer_type == HFI_BUFFER_OUTPUT2) { - if (*type == HFI_BUFFER_MODE_DYNAMIC && inst) - inst->cap_bufs_mode_dynamic = true; - + mode->buffer_type == HFI_BUFFER_OUTPUT2) for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain, fill_buf_mode, type, 1); - } type++; } -- 2.14.1
[PATCH v2 19/29] venus: helpers: add buffer type argument to a helper
This adds one more function argument to pass buffer type to set_output_resolution() helper function. That is a preparation to support secondary decoder output. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/helpers.c | 5 +++-- drivers/media/platform/qcom/venus/helpers.h | 3 ++- drivers/media/platform/qcom/venus/venc.c| 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 94664a3ce3e2..5512fbfdebb9 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -456,12 +456,13 @@ int venus_helper_set_input_resolution(struct venus_inst *inst, EXPORT_SYMBOL_GPL(venus_helper_set_input_resolution); int venus_helper_set_output_resolution(struct venus_inst *inst, - unsigned int width, unsigned int height) + unsigned int width, unsigned int height, + u32 buftype) { u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; struct hfi_framesize fs; - fs.buffer_type = HFI_BUFFER_OUTPUT; + fs.buffer_type = buftype; fs.width = width; fs.height = height; diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index cd306bd8978f..0de9989adcdb 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -36,7 +36,8 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, int venus_helper_set_input_resolution(struct venus_inst *inst, unsigned int width, unsigned int height); int venus_helper_set_output_resolution(struct venus_inst *inst, - unsigned int width, unsigned int height); + unsigned int width, unsigned int height, + u32 buftype); int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs, unsigned int output_bufs); int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt); diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index f87d891325ea..8970f14b3a82 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -795,7 +795,8 @@ static int venc_init_session(struct venus_inst *inst) goto deinit; ret = venus_helper_set_output_resolution(inst, inst->width, -inst->height); +inst->height, +HFI_BUFFER_OUTPUT); if (ret) goto deinit; -- 2.14.1
[PATCH v2 11/29] venus: venc,vdec: adds clocks needed for venus 4xx
This extends the clocks number to support suspend and resume on Venus version 4xx. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/core.h | 4 +-- drivers/media/platform/qcom/venus/vdec.c | 42 ++-- drivers/media/platform/qcom/venus/venc.c | 42 ++-- 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 8d3e150800c9..b5b9a84e9155 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -92,8 +92,8 @@ struct venus_core { void __iomem *base; int irq; struct clk *clks[VIDC_CLKS_NUM_MAX]; - struct clk *core0_clk; - struct clk *core1_clk; + struct clk *core0_clk, *core0_bus_clk; + struct clk *core1_clk, *core1_bus_clk; struct video_device *vdev_dec; struct video_device *vdev_enc; struct v4l2_device v4l2_dev; diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 261a51adeef2..c45452634e7e 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1081,12 +1081,18 @@ static int vdec_probe(struct platform_device *pdev) if (!core) return -EPROBE_DEFER; - if (core->res->hfi_version == HFI_VERSION_3XX) { + if (IS_V3(core) || IS_V4(core)) { core->core0_clk = devm_clk_get(dev, "core"); if (IS_ERR(core->core0_clk)) return PTR_ERR(core->core0_clk); } + if (IS_V4(core)) { + core->core0_bus_clk = devm_clk_get(dev, "bus"); + if (IS_ERR(core->core0_bus_clk)) + return PTR_ERR(core->core0_bus_clk); + } + platform_set_drvdata(pdev, core); vdev = video_device_alloc(); @@ -1132,12 +1138,23 @@ static __maybe_unused int vdec_runtime_suspend(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); - if (core->res->hfi_version == HFI_VERSION_1XX) + if (IS_V1(core)) return 0; - writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); + if (IS_V3(core)) + writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); + else if (IS_V4(core)) + writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL); + + if (IS_V4(core)) + clk_disable_unprepare(core->core0_bus_clk); + clk_disable_unprepare(core->core0_clk); - writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); + + if (IS_V3(core)) + writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); + else if (IS_V4(core)) + writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL); return 0; } @@ -1147,12 +1164,23 @@ static __maybe_unused int vdec_runtime_resume(struct device *dev) struct venus_core *core = dev_get_drvdata(dev); int ret; - if (core->res->hfi_version == HFI_VERSION_1XX) + if (IS_V1(core)) return 0; - writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); + if (IS_V3(core)) + writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); + else if (IS_V4(core)) + writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL); + ret = clk_prepare_enable(core->core0_clk); - writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); + + if (IS_V4(core)) + ret |= clk_prepare_enable(core->core0_bus_clk); + + if (IS_V3(core)) + writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL); + else if (IS_V4(core)) + writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL); return ret; } diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 947001170a77..bc8c2e7a8d2c 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1225,12 +1225,18 @@ static int venc_probe(struct platform_device *pdev) if (!core) return -EPROBE_DEFER; - if (core->res->hfi_version == HFI_VERSION_3XX) { + if (IS_V3(core) || IS_V4(core)) { core->core1_clk = devm_clk_get(dev, "core"); if (IS_ERR(core->core1_clk)) return PTR_ERR(core->core1_clk); } + if (IS_V4(core)) { + core->core1_bus_clk = devm_clk_get(dev, "bus"); + if (IS_ERR(core->core1_bus_clk)) + return PTR_ERR(core->core1_bus_clk); + } + platform_set_drvdata(pdev, core); vdev = video_device_alloc(); @@ -1276,12 +1282,23 @@ static __maybe_unused int venc_runtime_suspend(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev);
Re: [RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver
On 05/15/18 09:25, Neil Armstrong wrote: > Hi Hans, > > Thanks for the extensive review. > > On 15/05/2018 08:58, Hans Verkuil wrote: >> On 05/15/2018 12:40 AM, Neil Armstrong wrote: >>> The Chrome OS Embedded Controller can expose a CEC bus, this patch add the >>> driver for such feature of the Embedded Controller. >>> >>> This driver is part of the cros-ec MFD and will be add as a sub-device when >>> the feature bit is exposed by the EC. >>> >>> The controller will only handle a single logical address and handles >>> all the messages retries and will only expose Success or Error. >>> >>> When the logical address is invalid, the controller will act as a CEC >>> sniffer >>> and transfer all messages on the bus. >> >> I did not see any support for this. If this works as you state here, then >> adding >> support for CEC_CAP_MONITOR_ALL is highly recommended. > > Oops, I forgot to remove this phrase, the FW will maybe support it, but it > has been > dropped for the first revision. > >> >>> >>> Signed-off-by: Neil Armstrong >>> --- >>> drivers/media/platform/Kconfig | 11 + >>> drivers/media/platform/Makefile | 2 + >>> drivers/media/platform/cros-ec/Makefile | 1 + >>> drivers/media/platform/cros-ec/cros-ec-cec.c | 331 >>> +++ >>> 4 files changed, 345 insertions(+) >>> create mode 100644 drivers/media/platform/cros-ec/Makefile >>> create mode 100644 drivers/media/platform/cros-ec/cros-ec-cec.c >> >> Shouldn't the directory be called cros-ec-cec? >> >>> >>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig >>> index c7a1cf8..e55a8ed2 100644 >>> --- a/drivers/media/platform/Kconfig >>> +++ b/drivers/media/platform/Kconfig >>> @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS >>> >>> if CEC_PLATFORM_DRIVERS >>> >>> +config VIDEO_CROS_EC_CEC >>> + tristate "Chrome OS EC CEC driver" >>> + depends on MFD_CROS_EC || COMPILE_TEST >>> + select CEC_CORE >>> + select CEC_NOTIFIER >>> + ---help--- >>> + If you say yes here you will get support for the >>> + Chrome OS Embedded Controller's CEC. >>> + The CEC bus is present in the HDMI connector and enables communication >>> + between compatible devices. >>> + >>> config VIDEO_MESON_AO_CEC >>> tristate "Amlogic Meson AO CEC driver" >>> depends on ARCH_MESON || COMPILE_TEST >>> diff --git a/drivers/media/platform/Makefile >>> b/drivers/media/platform/Makefile >>> index 932515d..0e0582e 100644 >>> --- a/drivers/media/platform/Makefile >>> +++ b/drivers/media/platform/Makefile >>> @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= >>> qcom/camss-8x16/ >>> obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ >>> >>> obj-y += meson/ >>> + >>> +obj-y += cros-ec/ >>> diff --git a/drivers/media/platform/cros-ec/Makefile >>> b/drivers/media/platform/cros-ec/Makefile >>> new file mode 100644 >>> index 000..9ce97f9 >>> --- /dev/null >>> +++ b/drivers/media/platform/cros-ec/Makefile >>> @@ -0,0 +1 @@ >>> +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o >>> diff --git a/drivers/media/platform/cros-ec/cros-ec-cec.c >>> b/drivers/media/platform/cros-ec/cros-ec-cec.c >>> new file mode 100644 >>> index 000..fea90da >>> --- /dev/null >>> +++ b/drivers/media/platform/cros-ec/cros-ec-cec.c >>> @@ -0,0 +1,331 @@ >>> +// SPDX-License-Identifier: GPL-2.0+ >>> +/* >>> + * CEC driver for Chrome OS Embedded Controller >>> + * >>> + * Copyright (c) 2018 BayLibre, SAS >>> + * Author: Neil Armstrong >>> + */ >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#define DRV_NAME "cros-ec-cec" >>> + >>> +/** >>> + * struct cros_ec_cec - Driver data for EC CEC >>> + * >>> + * @cros_ec: Pointer to EC device >>> + * @notifier: Notifier info for responding to EC events >>> + * @adap: CEC adapter >>> + * @notify: CEC notifier pointer >>> + * @rc_msg: storage for a received message >>> + */ >>> +struct cros_ec_cec { >>> + struct cros_ec_device *cros_ec; >>> + struct notifier_block notifier; >>> + struct cec_adapter *adap; >>> + struct cec_notifier *notify; >>> + struct cec_msg rx_msg; >>> +}; >>> + >>> +static void handle_cec_message(struct cros_ec_cec *cros_ec_cec) >>> +{ >>> + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; >>> + uint8_t *cec_message = cros_ec->event_data.data.cec_message; >>> + unsigned int len = cros_ec->event_size; >>> + >>> + cros_ec_cec->rx_msg.len = len; >> >> How robust is the underlying code and hardware? What happens if a >> CEC message with more than 16 bytes is received? >> >> Hard to test unless you have an RPi3 set up as a CEC debugger. See >> last section in https://hverkuil.home.xs4all.nl/cec-status.txt. >> >> Since you worked with CEC for a while now I recommend you set up s
[PATCH v2 08/29] venus: hfi_venus: fix suspend function for venus 3xx versions
This fixes the suspend function for Venus 3xx versions by add a check for WFI (wait for interrupt) bit. This bit is on when the ARM9 is idle and entered in low power mode. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi_venus.c| 59 drivers/media/platform/qcom/venus/hfi_venus_io.h | 1 + 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index 53546174aab8..aac351f699a0 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -1447,7 +1447,7 @@ static int venus_suspend_3xx(struct venus_core *core) { struct venus_hfi_device *hdev = to_hfi_priv(core); struct device *dev = core->dev; - u32 ctrl_status, wfi_status; + u32 ctrl_status, cpu_status; int ret; int cnt = 100; @@ -1463,29 +1463,50 @@ static int venus_suspend_3xx(struct venus_core *core) return -EINVAL; } - ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0); - if (!(ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)) { - wfi_status = venus_readl(hdev, WRAPPER_CPU_STATUS); + /* +* Power collapse sequence for Venus 3xx and 4xx versions: +* 1. Check for ARM9 and video core to be idle by checking WFI bit +*(bit 0) in CPU status register and by checking Idle (bit 30) in +*Control status register for video core. +* 2. Send a command to prepare for power collapse. +* 3. Check for WFI and PC_READY bits. +*/ + + while (--cnt) { + cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS); ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0); - ret = venus_prepare_power_collapse(hdev, false); - if (ret) { - dev_err(dev, "prepare for power collapse fail (%d)\n", - ret); - return ret; - } + if (cpu_status & WRAPPER_CPU_STATUS_WFI && + ctrl_status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK) + break; - cnt = 100; - while (cnt--) { - wfi_status = venus_readl(hdev, WRAPPER_CPU_STATUS); - ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0); - if (ctrl_status & CPU_CS_SCIACMDARG0_PC_READY && - wfi_status & BIT(0)) - break; - usleep_range(1000, 1500); - } + usleep_range(1000, 1500); } + if (!cnt) + return -ETIMEDOUT; + + ret = venus_prepare_power_collapse(hdev, false); + if (ret) { + dev_err(dev, "prepare for power collapse fail (%d)\n", ret); + return ret; + } + + cnt = 100; + while (--cnt) { + cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS); + ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0); + + if (cpu_status & WRAPPER_CPU_STATUS_WFI && + ctrl_status & CPU_CS_SCIACMDARG0_PC_READY) + break; + + usleep_range(1000, 1500); + } + + if (!cnt) + return -ETIMEDOUT; + mutex_lock(&hdev->lock); ret = venus_power_off(hdev); diff --git a/drivers/media/platform/qcom/venus/hfi_venus_io.h b/drivers/media/platform/qcom/venus/hfi_venus_io.h index 76f47936d0fa..12e3d33a3d82 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus_io.h +++ b/drivers/media/platform/qcom/venus/hfi_venus_io.h @@ -108,6 +108,7 @@ #define WRAPPER_CPU_CGC_DIS(WRAPPER_BASE + 0x2010) #define WRAPPER_CPU_STATUS (WRAPPER_BASE + 0x2014) +#define WRAPPER_CPU_STATUS_WFI BIT(0) #define WRAPPER_SW_RESET (WRAPPER_BASE + 0x3000) /* Venus 4xx */ -- 2.14.1
[PATCH v2 09/29] venus: hfi_venus: move set of default properties to core init
This moves setting of default properties (firmware debug, idle indicator and low power mode) from session init to core init. All of those properties are need to be enabled/disabled early so that they could be used before the clients are even initialized. The other reason is to set idle indicator property early before we enter into venus_suspend function where we need to check for ARM9 WFI. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi_venus.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index aac351f699a0..284da69eb81b 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -1090,6 +1090,10 @@ static int venus_core_init(struct venus_core *core) if (ret) dev_warn(dev, "failed to send image version pkt to fw\n"); + ret = venus_sys_set_default_properties(hdev); + if (ret) + return ret; + return 0; } @@ -1134,10 +1138,6 @@ static int venus_session_init(struct venus_inst *inst, u32 session_type, struct hfi_session_init_pkt pkt; int ret; - ret = venus_sys_set_default_properties(hdev); - if (ret) - return ret; - ret = pkt_session_init(&pkt, inst, session_type, codec); if (ret) goto err; -- 2.14.1
[PATCH v2 05/29] venus: hfi: support session continue for 4xx version
This makes possible to handle session_continue for 4xx as well. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c index bca894a00c07..cbc6fad05e47 100644 --- a/drivers/media/platform/qcom/venus/hfi.c +++ b/drivers/media/platform/qcom/venus/hfi.c @@ -312,7 +312,7 @@ int hfi_session_continue(struct venus_inst *inst) { struct venus_core *core = inst->core; - if (core->res->hfi_version != HFI_VERSION_3XX) + if (core->res->hfi_version == HFI_VERSION_1XX) return 0; return core->ops->session_continue(inst); -- 2.14.1
[PATCH v2 07/29] venus: hfi_venus: add halt AXI support for Venus 4xx
Add AXI halt support for version 4xx by using venus wrapper registers. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi_venus.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index 734ce11b0ed0..53546174aab8 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -532,6 +532,23 @@ static int venus_halt_axi(struct venus_hfi_device *hdev) u32 val; int ret; + if (hdev->core->res->hfi_version == HFI_VERSION_4XX) { + val = venus_readl(hdev, WRAPPER_CPU_AXI_HALT); + val |= BIT(16); + venus_writel(hdev, WRAPPER_CPU_AXI_HALT, val); + + ret = readl_poll_timeout(base + WRAPPER_CPU_AXI_HALT_STATUS, +val, val & BIT(24), +POLL_INTERVAL_US, +VBIF_AXI_HALT_ACK_TIMEOUT_US); + if (ret) { + dev_err(dev, "AXI bus port halt timeout\n"); + return ret; + } + + return 0; + } + /* Halt AXI and AXI IMEM VBIF Access */ val = venus_readl(hdev, VBIF_AXI_HALT_CTRL0); val |= VBIF_AXI_HALT_CTRL0_HALT_REQ; -- 2.14.1
[PATCH v2 04/29] venus: hfi_cmds: add set_properties for 4xx version
Adds set_properties method to handle newer 4xx properties and fall-back to 3xx for the rest. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi_cmds.c | 64 +++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c index 1cfeb7743041..6bd287154796 100644 --- a/drivers/media/platform/qcom/venus/hfi_cmds.c +++ b/drivers/media/platform/qcom/venus/hfi_cmds.c @@ -1166,6 +1166,65 @@ pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt, return ret; } +static int +pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt, +void *cookie, u32 ptype, void *pdata) +{ + void *prop_data; + int ret = 0; + + if (!pkt || !cookie || !pdata) + return -EINVAL; + + prop_data = &pkt->data[1]; + + pkt->shdr.hdr.size = sizeof(*pkt); + pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY; + pkt->shdr.session_id = hash32_ptr(cookie); + pkt->num_properties = 1; + pkt->data[0] = ptype; + + /* +* Any session set property which is different in 3XX packetization +* should be added as a new case below. All unchanged session set +* properties will be handled in the default case. +*/ + switch (ptype) { + case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: { + struct hfi_buffer_count_actual *in = pdata; + struct hfi_buffer_count_actual_4xx *count = prop_data; + + count->count_actual = in->count_actual; + count->type = in->type; + count->count_min_host = in->count_actual; + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count); + break; + } + case HFI_PROPERTY_PARAM_WORK_MODE: { + struct hfi_video_work_mode *in = pdata, *wm = prop_data; + + wm->video_work_mode = in->video_work_mode; + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*wm); + break; + } + case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: { + struct hfi_videocores_usage_type *in = pdata, *cu = prop_data; + + cu->video_core_enable_mask = in->video_core_enable_mask; + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cu); + break; + } + case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE: + /* not implemented on Venus 4xx */ + break; + default: + ret = pkt_session_set_property_3xx(pkt, cookie, ptype, pdata); + break; + } + + return ret; +} + int pkt_session_get_property(struct hfi_session_get_property_pkt *pkt, void *cookie, u32 ptype) { @@ -1181,7 +1240,10 @@ int pkt_session_set_property(struct hfi_session_set_property_pkt *pkt, if (hfi_ver == HFI_VERSION_1XX) return pkt_session_set_property_1x(pkt, cookie, ptype, pdata); - return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata); + if (hfi_ver == HFI_VERSION_3XX) + return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata); + + return pkt_session_set_property_4xx(pkt, cookie, ptype, pdata); } void pkt_set_version(enum hfi_version version) -- 2.14.1
[PATCH v2 06/29] venus: hfi: handle buffer output2 type as well
This adds handling of buffers of type OUTPUT2 which is needed to support Venus 4xx version. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi.c | 3 ++- drivers/media/platform/qcom/venus/hfi_msgs.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c index cbc6fad05e47..a570fdad0de0 100644 --- a/drivers/media/platform/qcom/venus/hfi.c +++ b/drivers/media/platform/qcom/venus/hfi.c @@ -473,7 +473,8 @@ int hfi_session_process_buf(struct venus_inst *inst, struct hfi_frame_data *fd) if (fd->buffer_type == HFI_BUFFER_INPUT) return ops->session_etb(inst, fd); - else if (fd->buffer_type == HFI_BUFFER_OUTPUT) + else if (fd->buffer_type == HFI_BUFFER_OUTPUT || +fd->buffer_type == HFI_BUFFER_OUTPUT2) return ops->session_ftb(inst, fd); return -EINVAL; diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index 5970e9b1716b..023802e62833 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -825,7 +825,8 @@ static void hfi_session_ftb_done(struct venus_core *core, error = HFI_ERR_SESSION_INVALID_PARAMETER; } - if (buffer_type != HFI_BUFFER_OUTPUT) + if (buffer_type != HFI_BUFFER_OUTPUT && + buffer_type != HFI_BUFFER_OUTPUT2) goto done; if (hfi_flags & HFI_BUFFERFLAG_EOS) -- 2.14.1
[PATCH v2 01/29] venus: hfi_msgs: correct pointer increment
Data pointer should be incremented by size of the structure not the size of a pointer, correct the mistake. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi_msgs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index 90c93d9603dc..589e1a6b36a9 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -60,14 +60,14 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, frame_sz = (struct hfi_framesize *)data_ptr; event.width = frame_sz->width; event.height = frame_sz->height; - data_ptr += sizeof(frame_sz); + data_ptr += sizeof(*frame_sz); break; case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: data_ptr += sizeof(u32); profile_level = (struct hfi_profile_level *)data_ptr; event.profile = profile_level->profile; event.level = profile_level->level; - data_ptr += sizeof(profile_level); + data_ptr += sizeof(*profile_level); break; default: break; -- 2.14.1
[PATCH v2 03/29] venus: hfi: update sequence event to handle more properties
HFI version 4xx can pass more properties in the sequence change event, extend the event structure with them. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/hfi.h | 9 ++ drivers/media/platform/qcom/venus/hfi_msgs.c | 46 2 files changed, 55 insertions(+) diff --git a/drivers/media/platform/qcom/venus/hfi.h b/drivers/media/platform/qcom/venus/hfi.h index 5466b7d60dd0..21376d93170f 100644 --- a/drivers/media/platform/qcom/venus/hfi.h +++ b/drivers/media/platform/qcom/venus/hfi.h @@ -74,6 +74,15 @@ struct hfi_event_data { u32 tag; u32 profile; u32 level; + u32 bit_depth; + u32 pic_struct; + u32 colour_space; + u32 entropy_mode; + u32 buf_count; + struct { + u32 left, top; + u32 width, height; + } input_crop; }; /* define core states */ diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index 589e1a6b36a9..5970e9b1716b 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -25,10 +25,17 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, struct hfi_msg_event_notify_pkt *pkt) { + enum hfi_version ver = core->res->hfi_version; struct hfi_event_data event = {0}; int num_properties_changed; struct hfi_framesize *frame_sz; struct hfi_profile_level *profile_level; + struct hfi_bit_depth *pixel_depth; + struct hfi_pic_struct *pic_struct; + struct hfi_colour_space *colour_info; + struct hfi_buffer_requirements *bufreq; + struct hfi_extradata_input_crop *crop; + u32 entropy_mode = 0; u8 *data_ptr; u32 ptype; @@ -69,6 +76,45 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, event.level = profile_level->level; data_ptr += sizeof(*profile_level); break; + case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: + data_ptr += sizeof(u32); + pixel_depth = (struct hfi_bit_depth *)data_ptr; + event.bit_depth = pixel_depth->bit_depth; + data_ptr += sizeof(*pixel_depth); + break; + case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: + data_ptr += sizeof(u32); + pic_struct = (struct hfi_pic_struct *)data_ptr; + event.pic_struct = pic_struct->progressive_only; + data_ptr += sizeof(*pic_struct); + break; + case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: + data_ptr += sizeof(u32); + colour_info = (struct hfi_colour_space *)data_ptr; + event.colour_space = colour_info->colour_space; + data_ptr += sizeof(*colour_info); + break; + case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: + data_ptr += sizeof(u32); + entropy_mode = *(u32 *)data_ptr; + event.entropy_mode = entropy_mode; + data_ptr += sizeof(u32); + break; + case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: + data_ptr += sizeof(u32); + bufreq = (struct hfi_buffer_requirements *)data_ptr; + event.buf_count = HFI_BUFREQ_COUNT_MIN(bufreq, ver); + data_ptr += sizeof(*bufreq); + break; + case HFI_INDEX_EXTRADATA_INPUT_CROP: + data_ptr += sizeof(u32); + crop = (struct hfi_extradata_input_crop *)data_ptr; + event.input_crop.left = crop->left; + event.input_crop.top = crop->top; + event.input_crop.width = crop->width; + event.input_crop.height = crop->height; + data_ptr += sizeof(*crop); + break; default: break; } -- 2.14.1
[PATCH v2 02/29] venus: hfi: preparation to support venus 4xx
This covers the differences between 1xx,3xx and 4xx. Signed-off-by: Stanimir Varbanov --- drivers/media/platform/qcom/venus/core.h | 4 ++ drivers/media/platform/qcom/venus/helpers.c | 37 +++ drivers/media/platform/qcom/venus/hfi_helper.h | 84 ++-- drivers/media/platform/qcom/venus/hfi_venus_io.h | 24 +++ drivers/media/platform/qcom/venus/vdec.c | 5 +- drivers/media/platform/qcom/venus/venc.c | 5 +- 6 files changed, 137 insertions(+), 22 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 0360d295f4c8..8d3e150800c9 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -305,6 +305,10 @@ struct venus_inst { struct hfi_buffer_requirements bufreq[HFI_BUFFER_TYPE_MAX]; }; +#define IS_V1(core)((core)->res->hfi_version == HFI_VERSION_1XX) +#define IS_V3(core)((core)->res->hfi_version == HFI_VERSION_3XX) +#define IS_V4(core)((core)->res->hfi_version == HFI_VERSION_4XX) + #define ctrl_to_inst(ctrl) \ container_of((ctrl)->handler, struct venus_inst, ctrl_handler) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 0ce9559a2924..d9065cc8a7d3 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -166,21 +166,37 @@ static int intbufs_unset_buffers(struct venus_inst *inst) return ret; } -static const unsigned int intbuf_types[] = { - HFI_BUFFER_INTERNAL_SCRATCH, - HFI_BUFFER_INTERNAL_SCRATCH_1, - HFI_BUFFER_INTERNAL_SCRATCH_2, +static const unsigned int intbuf_types_1xx[] = { + HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_1XX), + HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_1XX), + HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_1XX), + HFI_BUFFER_INTERNAL_PERSIST, + HFI_BUFFER_INTERNAL_PERSIST_1, +}; + +static const unsigned int intbuf_types_4xx[] = { + HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_4XX), + HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_4XX), + HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_4XX), HFI_BUFFER_INTERNAL_PERSIST, HFI_BUFFER_INTERNAL_PERSIST_1, }; static int intbufs_alloc(struct venus_inst *inst) { - unsigned int i; + size_t arr_sz; + size_t i; int ret; - for (i = 0; i < ARRAY_SIZE(intbuf_types); i++) { - ret = intbufs_set_buffer(inst, intbuf_types[i]); + if (IS_V4(inst->core)) + arr_sz = ARRAY_SIZE(intbuf_types_4xx); + else + arr_sz = ARRAY_SIZE(intbuf_types_1xx); + + for (i = 0; i < arr_sz; i++) { + ret = intbufs_set_buffer(inst, + IS_V4(inst->core) ? intbuf_types_4xx[i] : + intbuf_types_1xx[i]); if (ret) goto error; } @@ -257,12 +273,11 @@ static int load_scale_clocks(struct venus_core *core) set_freq: - if (core->res->hfi_version == HFI_VERSION_3XX) { - ret = clk_set_rate(clk, freq); + ret = clk_set_rate(clk, freq); + + if (IS_V3(core) || IS_V4(core)) { ret |= clk_set_rate(core->core0_clk, freq); ret |= clk_set_rate(core->core1_clk, freq); - } else { - ret = clk_set_rate(clk, freq); } if (ret) { diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h index 55d8eb21403a..1bc5aab1ce6b 100644 --- a/drivers/media/platform/qcom/venus/hfi_helper.h +++ b/drivers/media/platform/qcom/venus/hfi_helper.h @@ -121,6 +121,7 @@ #define HFI_EXTRADATA_METADATA_FILLER 0x7fe2 #define HFI_INDEX_EXTRADATA_INPUT_CROP 0x070e +#define HFI_INDEX_EXTRADATA_OUTPUT_CROP0x070f #define HFI_INDEX_EXTRADATA_DIGITAL_ZOOM 0x0710 #define HFI_INDEX_EXTRADATA_ASPECT_RATIO 0x7f13 @@ -376,13 +377,18 @@ #define HFI_BUFFER_OUTPUT2 0x3 #define HFI_BUFFER_INTERNAL_PERSIST0x4 #define HFI_BUFFER_INTERNAL_PERSIST_1 0x5 -#define HFI_BUFFER_INTERNAL_SCRATCH0x101 -#define HFI_BUFFER_EXTRADATA_INPUT 0x102 -#define HFI_BUFFER_EXTRADATA_OUTPUT0x103 -#define HFI_BUFFER_EXTRADATA_OUTPUT2 0x104 -#define HFI_BUFFER_INTERNAL_SCRATCH_1 0x105 -#define HFI_BUFFER_INTERNAL_SCRATCH_2 0x106 - +#define HFI_BUFFER_INTERNAL_SCRATCH(ver) \ + (((ver) == HFI_VERSION_4XX) ? 0x6 : 0x101) +#define HFI_BUFFER_INTERNAL_SCRATCH_1(ver) \ + (((ver) == HFI_VERSION_4XX) ? 0x7 : 0x105) +#define HFI_BUFFER_INTERNAL_SCRATCH_2(ver) \ + (((ver) == HFI_VERSION_4XX) ? 0x8 : 0x106) +#define HFI_BUFFER_EXTRA
[PATCH v2 00/29] Venus updates
Hello, Here is v2 with following comments addressed: * reworked venus suspend 3xx and reuse it for 4xx. * drop 10/28 patch from v1, i.e. call of session_continue when buffer requirements are not sufficient. * fixed kbuild test robot warning in 11/28 by allocating instance variable from heap. * spelling typo in 15/28. * added Reviewed-by for DT changes. * extended 28/28 HEVC support for encoder, now the profile and level are selected properly. Comments are welcome! regards, Stan Stanimir Varbanov (29): venus: hfi_msgs: correct pointer increment venus: hfi: preparation to support venus 4xx venus: hfi: update sequence event to handle more properties venus: hfi_cmds: add set_properties for 4xx version venus: hfi: support session continue for 4xx version venus: hfi: handle buffer output2 type as well venus: hfi_venus: add halt AXI support for Venus 4xx venus: hfi_venus: fix suspend function for venus 3xx versions venus: hfi_venus: move set of default properties to core init venus: hfi_venus: add suspend functionality for Venus 4xx venus: venc,vdec: adds clocks needed for venus 4xx venus: add common capability parser venus: helpers: make a commmon function for power_enable venus: core: delete not used flag for buffer mode venus: helpers: rename a helper function and use buffer mode from caps venus: add a helper function to set dynamic buffer mode venus: add helper function to set actual buffer size venus: delete no longer used bufmode flag from instance venus: helpers: add buffer type argument to a helper venus: helpers: add a new helper to set raw format venus: helpers,vdec,venc: add helpers to set work mode and core usage venus: helpers: extend set_num_bufs helper with one more argument venus: helpers: add a helper to return opb buffer sizes venus: vdec: get required input buffers as well venus: vdec: new function for output configuration venus: move frame size calculations in common place venus: implementing multi-stream support venus: add sdm845 compatible and resource data venus: add HEVC codec support .../devicetree/bindings/media/qcom,venus.txt | 1 + drivers/media/platform/qcom/venus/Makefile | 3 +- drivers/media/platform/qcom/venus/core.c | 107 drivers/media/platform/qcom/venus/core.h | 93 ++-- drivers/media/platform/qcom/venus/helpers.c| 558 +++-- drivers/media/platform/qcom/venus/helpers.h| 23 +- drivers/media/platform/qcom/venus/hfi.c| 12 +- drivers/media/platform/qcom/venus/hfi.h| 9 + drivers/media/platform/qcom/venus/hfi_cmds.c | 64 ++- drivers/media/platform/qcom/venus/hfi_helper.h | 112 - drivers/media/platform/qcom/venus/hfi_msgs.c | 401 +++ drivers/media/platform/qcom/venus/hfi_parser.c | 291 +++ drivers/media/platform/qcom/venus/hfi_parser.h | 45 ++ drivers/media/platform/qcom/venus/hfi_venus.c | 95 +++- drivers/media/platform/qcom/venus/hfi_venus_io.h | 25 + drivers/media/platform/qcom/venus/vdec.c | 316 +++- drivers/media/platform/qcom/venus/venc.c | 211 17 files changed, 1689 insertions(+), 677 deletions(-) create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.c create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.h -- 2.14.1
Re: [PATCH v2 27/29] venus: implementing multi-stream support
Hi Stanimir, On 05/15/18 09:58, Stanimir Varbanov wrote: > This is implementing a multi-stream decoder support. The multi > stream gives an option to use the secondary decoder output > with different raw format (or the same in case of crop). You told me that multi-stream support is currently internal only. It would be good if you could elaborate a bit about that in this commit log and (I think) also add some comments in the code that reflect this. It's also not clear to me how and why this is used in the driver if this is just internal. Does it enable a feature you would otherwise not be able to use? I have no complaints about the code, I would just like to see a bit more background information in the source and commit log. Regards, Hans > > Signed-off-by: Stanimir Varbanov > --- > drivers/media/platform/qcom/venus/core.h| 1 + > drivers/media/platform/qcom/venus/helpers.c | 204 > +++- > drivers/media/platform/qcom/venus/helpers.h | 6 + > drivers/media/platform/qcom/venus/vdec.c| 91 - > drivers/media/platform/qcom/venus/venc.c| 1 + > 5 files changed, 299 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/platform/qcom/venus/core.h > b/drivers/media/platform/qcom/venus/core.h > index 4d6c05f156c4..85e66e2dd672 100644 > --- a/drivers/media/platform/qcom/venus/core.h > +++ b/drivers/media/platform/qcom/venus/core.h > @@ -259,6 +259,7 @@ struct venus_inst { > struct list_head list; > struct mutex lock; > struct venus_core *core; > + struct list_head dpbbufs; > struct list_head internalbufs; > struct list_head registeredbufs; > struct list_head delayed_process; > diff --git a/drivers/media/platform/qcom/venus/helpers.c > b/drivers/media/platform/qcom/venus/helpers.c > index ed569705ecac..87dcf9973e6f 100644 > --- a/drivers/media/platform/qcom/venus/helpers.c > +++ b/drivers/media/platform/qcom/venus/helpers.c > @@ -85,6 +85,112 @@ bool venus_helper_check_codec(struct venus_inst *inst, > u32 v4l2_pixfmt) > } > EXPORT_SYMBOL_GPL(venus_helper_check_codec); > > +static int venus_helper_queue_dpb_bufs(struct venus_inst *inst) > +{ > + struct intbuf *buf; > + int ret = 0; > + > + if (list_empty(&inst->dpbbufs)) > + return 0; > + > + list_for_each_entry(buf, &inst->dpbbufs, list) { > + struct hfi_frame_data fdata; > + > + memset(&fdata, 0, sizeof(fdata)); > + fdata.alloc_len = buf->size; > + fdata.device_addr = buf->da; > + fdata.buffer_type = buf->type; > + > + ret = hfi_session_process_buf(inst, &fdata); > + if (ret) > + goto fail; > + } > + > +fail: > + return ret; > +} > + > +int venus_helper_free_dpb_bufs(struct venus_inst *inst) > +{ > + struct intbuf *buf, *n; > + > + if (list_empty(&inst->dpbbufs)) > + return 0; > + > + list_for_each_entry_safe(buf, n, &inst->dpbbufs, list) { > + list_del_init(&buf->list); > + dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, > +buf->attrs); > + kfree(buf); > + } > + > + INIT_LIST_HEAD(&inst->dpbbufs); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(venus_helper_free_dpb_bufs); > + > +int venus_helper_alloc_dpb_bufs(struct venus_inst *inst) > +{ > + struct venus_core *core = inst->core; > + struct device *dev = core->dev; > + enum hfi_version ver = core->res->hfi_version; > + struct hfi_buffer_requirements bufreq; > + u32 buftype = inst->dpb_buftype; > + unsigned int dpb_size = 0; > + struct intbuf *buf; > + unsigned int i; > + u32 count; > + int ret; > + > + /* no need to allocate dpb buffers */ > + if (!inst->dpb_fmt) > + return 0; > + > + if (inst->dpb_buftype == HFI_BUFFER_OUTPUT) > + dpb_size = inst->output_buf_size; > + else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2) > + dpb_size = inst->output2_buf_size; > + > + if (!dpb_size) > + return 0; > + > + ret = venus_helper_get_bufreq(inst, buftype, &bufreq); > + if (ret) > + return ret; > + > + count = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); > + > + for (i = 0; i < count; i++) { > + buf = kzalloc(sizeof(*buf), GFP_KERNEL); > + if (!buf) { > + ret = -ENOMEM; > + goto fail; > + } > + > + buf->type = buftype; > + buf->size = dpb_size; > + buf->attrs = DMA_ATTR_WRITE_COMBINE | > + DMA_ATTR_NO_KERNEL_MAPPING; > + buf->va = dma_alloc_attrs(dev, buf->size, &buf->da, GFP_KERNEL, > + buf->attrs); > + if (!buf->va) { > + kfree(buf); > + ret = -ENOMEM; > + goto fail; > +
Re: [PATCH v2 00/29] Venus updates
Hi Stanimir, On 05/15/18 09:58, Stanimir Varbanov wrote: > Hello, > > Here is v2 with following comments addressed: > > * reworked venus suspend 3xx and reuse it for 4xx. > * drop 10/28 patch from v1, i.e. call of session_continue when > buffer requirements are not sufficient. > * fixed kbuild test robot warning in 11/28 by allocating instance > variable from heap. > * spelling typo in 15/28. > * added Reviewed-by for DT changes. > * extended 28/28 HEVC support for encoder, now the profile and > level are selected properly. > > Comments are welcome! It all looks good, except for patch 27 (see my comments there). Once there is a v3 for patch 27 and I'm OK with it, then just let me know when it is ready in your opinion to be merged. Regards, Hans > > regards, > Stan > > Stanimir Varbanov (29): > venus: hfi_msgs: correct pointer increment > venus: hfi: preparation to support venus 4xx > venus: hfi: update sequence event to handle more properties > venus: hfi_cmds: add set_properties for 4xx version > venus: hfi: support session continue for 4xx version > venus: hfi: handle buffer output2 type as well > venus: hfi_venus: add halt AXI support for Venus 4xx > venus: hfi_venus: fix suspend function for venus 3xx versions > venus: hfi_venus: move set of default properties to core init > venus: hfi_venus: add suspend functionality for Venus 4xx > venus: venc,vdec: adds clocks needed for venus 4xx > venus: add common capability parser > venus: helpers: make a commmon function for power_enable > venus: core: delete not used flag for buffer mode > venus: helpers: rename a helper function and use buffer mode from caps > venus: add a helper function to set dynamic buffer mode > venus: add helper function to set actual buffer size > venus: delete no longer used bufmode flag from instance > venus: helpers: add buffer type argument to a helper > venus: helpers: add a new helper to set raw format > venus: helpers,vdec,venc: add helpers to set work mode and core usage > venus: helpers: extend set_num_bufs helper with one more argument > venus: helpers: add a helper to return opb buffer sizes > venus: vdec: get required input buffers as well > venus: vdec: new function for output configuration > venus: move frame size calculations in common place > venus: implementing multi-stream support > venus: add sdm845 compatible and resource data > venus: add HEVC codec support > > .../devicetree/bindings/media/qcom,venus.txt | 1 + > drivers/media/platform/qcom/venus/Makefile | 3 +- > drivers/media/platform/qcom/venus/core.c | 107 > drivers/media/platform/qcom/venus/core.h | 93 ++-- > drivers/media/platform/qcom/venus/helpers.c| 558 > +++-- > drivers/media/platform/qcom/venus/helpers.h| 23 +- > drivers/media/platform/qcom/venus/hfi.c| 12 +- > drivers/media/platform/qcom/venus/hfi.h| 9 + > drivers/media/platform/qcom/venus/hfi_cmds.c | 64 ++- > drivers/media/platform/qcom/venus/hfi_helper.h | 112 - > drivers/media/platform/qcom/venus/hfi_msgs.c | 401 +++ > drivers/media/platform/qcom/venus/hfi_parser.c | 291 +++ > drivers/media/platform/qcom/venus/hfi_parser.h | 45 ++ > drivers/media/platform/qcom/venus/hfi_venus.c | 95 +++- > drivers/media/platform/qcom/venus/hfi_venus_io.h | 25 + > drivers/media/platform/qcom/venus/vdec.c | 316 +++- > drivers/media/platform/qcom/venus/venc.c | 211 > 17 files changed, 1689 insertions(+), 677 deletions(-) > create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.c > create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.h >
Re: Are media drivers abusing of GFP_DMA? - was: Re: [LSF/MM TOPIC NOTES] x86 ZONE_DMA love
Hello, On Tuesday, 15 May 2018 10:30:28 EEST Fabien DESSENNE wrote: > On 14/05/18 12:39, Mauro Carvalho Chehab wrote: > > Em Mon, 14 May 2018 07:35:03 -0300 Mauro Carvalho Chehab escreveu: > >> Em Mon, 14 May 2018 08:00:37 + Fabien DESSENNE escreveu: > >>> On 07/05/18 17:19, Mauro Carvalho Chehab wrote: > Em Mon, 07 May 2018 16:26:08 +0300 Laurent Pinchart escreveu: > > On Saturday, 5 May 2018 19:08:15 EEST Mauro Carvalho Chehab wrote: > > > >> There was a recent discussion about the use/abuse of GFP_DMA flag > >> when allocating memories at LSF/MM 2018 (see Luis notes enclosed). > >> > >> The idea seems to be to remove it, using CMA instead. Before doing > >> that, better to check if what we have on media is are valid use cases > >> for it, or if it is there just due to some misunderstanding (or > >> because it was copied from some other code). > >> > >> Hans de Goede sent us today a patch stopping abuse at gspca, and I'm > >> also posting today two other patches meant to stop abuse of it on > >> USB drivers. Still, there are 4 platform drivers using it: > >> > >>$ git grep -l -E "GFP_DMA\\b" drivers/media/ > >>drivers/media/platform/omap3isp/ispstat.c > >>drivers/media/platform/sti/bdisp/bdisp-hw.c > >>drivers/media/platform/sti/hva/hva-mem.c > >>> > >>> The two STI drivers (bdisp-hw.c and hva-mem.c) are only expected to run > >>> on ARM platforms, not on x86. Since this thread deals with x86 & DMA > >>> trouble, I am not sure that we actually have a problem for the sti > >>> drivers. > >>> > >>> There are some other sti drivers that make use of this GFP_DMA flag > >>> (drivers/gpu/drm/sti/sti_*.c) and it does not seem to be a problem. > >>> > >>> Nevertheless I can see that the media sti drivers depend on COMPILE_TEST > >>> (which is not the case for the DRM ones). > >>> Would it be an acceptable solution to remove the COMPILE_TEST > >>> dependency? > >> > >> This has nothing to do with either x86 or COMPILE_TEST. The thing is > >> that there's a plan for removing GFP_DMA from the Kernel[1], as it was > >> originally meant to be used only by old PCs, where the DMA controllers > >> used only on the bottom 16 MB memory address (24 bits). IMHO, it is > >> very unlikely that any ARM SoC have such limitation. > >> > >> [1] https://lwn.net/Articles/753273/ (article will be freely available > >> on May, 17) > > > > Btw, you can also read about that at: > > > > https://lwn.net/Articles/753274/ > > > >> Anyway, before the removal of GFP_DMA happens, I'd like to better > >> understand why we're using it at media, and if we can, instead, > >> set the DMA bit mask, just like almost all other media drivers > >> that require to confine DMA into a certain range do. In the case > >> of ARM, this is what we currently have: > >> > >> drivers/media/platform/exynos-gsc/gsc-core.c: > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > >> drivers/media/platform/exynos4-is/fimc-core.c: > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > >> drivers/media/platform/exynos4-is/fimc-is.c: > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > >> drivers/media/platform/exynos4-is/fimc-lite.c: > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > >> drivers/media/platform/mtk-mdp/mtk_mdp_core.c: > >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); > >> drivers/media/platform/omap3isp/isp.c: ret = > >> dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); > >> drivers/media/platform/s5p-g2d/g2d.c: > >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); > >> drivers/media/platform/s5p-jpeg/jpeg-core.c: > >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); > >> drivers/media/platform/s5p-mfc/s5p_mfc.c: > >>DMA_BIT_MASK(32)); > >> drivers/media/platform/s5p-mfc/s5p_mfc.c: > >> DMA_BIT_MASK(32)); > >> drivers/media/platform/s5p-mfc/s5p_mfc.c: > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > > That's clearer now, thank you for the clarification > I am about to send patches for the sti drivers (set the DMA bit mask) Some drivers call vb2_dma_contig_set_max_seg_size() and some call dma_coerce_mask_and_coherent(). Both are likely needed, the former telling the DMA mapping API about the maximum size of a scatter-gather chunk that the device supports (when using vb2-dma-contig that size should really be the full address space supported by the device as we want DMA-contiguous buffers), and the latter telling the DMA mapping API about the address space that is accessible through DMA (and thus in which address range buffers must be placed). I wonder why the omap3isp driver works without a vb2_dma_contig_set_max_seg_size() call. Sakari, any insight ? > >>drivers/media/spi/cxd2880-spi.c > >> > >> Could you
Re: [RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver
On 15/05/2018 10:10, Hans Verkuil wrote: > On 05/15/18 09:25, Neil Armstrong wrote: >> Hi Hans, >> >> Thanks for the extensive review. >> >> On 15/05/2018 08:58, Hans Verkuil wrote: >>> On 05/15/2018 12:40 AM, Neil Armstrong wrote: The Chrome OS Embedded Controller can expose a CEC bus, this patch add the driver for such feature of the Embedded Controller. This driver is part of the cros-ec MFD and will be add as a sub-device when the feature bit is exposed by the EC. The controller will only handle a single logical address and handles all the messages retries and will only expose Success or Error. When the logical address is invalid, the controller will act as a CEC sniffer and transfer all messages on the bus. >>> >>> I did not see any support for this. If this works as you state here, then >>> adding >>> support for CEC_CAP_MONITOR_ALL is highly recommended. >> >> Oops, I forgot to remove this phrase, the FW will maybe support it, but it >> has been >> dropped for the first revision. >> >>> Signed-off-by: Neil Armstrong --- drivers/media/platform/Kconfig | 11 + drivers/media/platform/Makefile | 2 + drivers/media/platform/cros-ec/Makefile | 1 + drivers/media/platform/cros-ec/cros-ec-cec.c | 331 +++ 4 files changed, 345 insertions(+) create mode 100644 drivers/media/platform/cros-ec/Makefile create mode 100644 drivers/media/platform/cros-ec/cros-ec-cec.c >>> >>> Shouldn't the directory be called cros-ec-cec? Forgot this one, moved to cros-ec-cec directory. >>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index c7a1cf8..e55a8ed2 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS if CEC_PLATFORM_DRIVERS +config VIDEO_CROS_EC_CEC + tristate "Chrome OS EC CEC driver" + depends on MFD_CROS_EC || COMPILE_TEST + select CEC_CORE + select CEC_NOTIFIER + ---help--- +If you say yes here you will get support for the +Chrome OS Embedded Controller's CEC. +The CEC bus is present in the HDMI connector and enables communication +between compatible devices. + config VIDEO_MESON_AO_CEC tristate "Amlogic Meson AO CEC driver" depends on ARCH_MESON || COMPILE_TEST diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 932515d..0e0582e 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss-8x16/ obj-$(CONFIG_VIDEO_QCOM_VENUS)+= qcom/venus/ obj-y += meson/ + +obj-y += cros-ec/ diff --git a/drivers/media/platform/cros-ec/Makefile b/drivers/media/platform/cros-ec/Makefile new file mode 100644 index 000..9ce97f9 --- /dev/null +++ b/drivers/media/platform/cros-ec/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o diff --git a/drivers/media/platform/cros-ec/cros-ec-cec.c b/drivers/media/platform/cros-ec/cros-ec-cec.c new file mode 100644 index 000..fea90da --- /dev/null +++ b/drivers/media/platform/cros-ec/cros-ec-cec.c @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * CEC driver for Chrome OS Embedded Controller + * + * Copyright (c) 2018 BayLibre, SAS + * Author: Neil Armstrong + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "cros-ec-cec" + +/** + * struct cros_ec_cec - Driver data for EC CEC + * + * @cros_ec: Pointer to EC device + * @notifier: Notifier info for responding to EC events + * @adap: CEC adapter + * @notify: CEC notifier pointer + * @rc_msg: storage for a received message + */ +struct cros_ec_cec { + struct cros_ec_device *cros_ec; + struct notifier_block notifier; + struct cec_adapter *adap; + struct cec_notifier *notify; + struct cec_msg rx_msg; +}; + +static void handle_cec_message(struct cros_ec_cec *cros_ec_cec) +{ + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; + uint8_t *cec_message = cros_ec->event_data.data.cec_message; + unsigned int len = cros_ec->event_size; + + cros_ec_cec->rx_msg.len = len; >>> >>> How robust is the underlying code and hardware? What happens if a >>> CEC message with more than 16 bytes is received?
Re: [RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver
On 05/15/18 10:28, Neil Armstrong wrote: > + int ret; > + > + cros_ec_cec = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_cec), > +GFP_KERNEL); > + if (!cros_ec_cec) > + return -ENOMEM; > + > + platform_set_drvdata(pdev, cros_ec_cec); > + cros_ec_cec->cros_ec = cros_ec; > + > + ret = cros_ec_cec_get_notifier(&cros_ec_cec->notify); > + if (ret) { > + dev_warn(&pdev->dev, "no CEC notifier available\n"); > + cec_caps |= CEC_CAP_PHYS_ADDR; Can this happen? What hardware has this? I am strongly opposed to CEC drivers using this capability unless there is no other option. It's a pain for userspace. >>> >>> It's in case an HW having a CEC capable FW but not in the >>> cec_dmi_match_table, in this case >>> it won't fail but still enable the CEC interface without a notifier. >> >> I don't think that's a good idea. CAP_PHYS_ADDR should *only* be used in >> situations >> where it is truly impossible to tell which output is connected to the CEC >> adapter. >> That's the case with e.g. USB CEC dongles where you have no idea how the user >> connected the HDMI cables. >> >> But I assume that in this case it just means that the cec_dmi_match_table >> needs >> to be updated, i.e. it is a driver bug. > > Yep, maybe a dev_warn should be added to notify this bug ? Yes, a dev_warn and then return -ENODEV. > >> >> Another thing: this driver assumes that there is only one CEC adapter for >> only >> one HDMI output. But what if there are more HDMI outputs? Will there be one >> CEC adapter for each output? Or does the hardware have no provisions for >> that? > > The current EC interface only exposes a single CEC interface for now, there > is no > plan yet for multiple HDMI outputs handling. > >> >> Something should be mentioned about this in a comment. > > Ok Thanks! Hans
Hello
Dear Friend, I am Mr. Joel TOURE,a banker by profession and I work with one of the largest bank here as the Group Managing Director/Chief Executive Officer. Meanwhile,I'm seriously in need of a partner then I decide to contact you believing that you can partner with me as I have opportunity to transfer overdue funds worth Four Million Five Hundred Thousand US dollars (US$4,500.000.00) out from my bank and i need a serious and Trustworthy partner who can provide a reliable bank account where the money can be transfer . So, if you interested and agree with me then contact me here ( elume...@aol.fr ) and i will give you full details. Mr. Joel TOURE +22675329619
[PATCH] adv7511: fix clearing of the CEC receive buffer
The CEC receive buffer was not always cleared correctly. The datasheet was a bit confusing since sometimes it mentioned that the bit in CEC register 0x4a had to be toggled, and sometimes it suggested it was a 'Clear-on-write' bit. But it really needs to be toggled. The patch also enables/disables the CEC irqs after the other irq are enabled/disabled instead of doing it before. It may not matter, but it feels more logical to do it in that order, and the implementation that we (Cisco) have used until now and that is known to be reliable also did it in that order. Signed-off-by: Hans Verkuil --- diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index d23505a411ee..d4b191c5ac47 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -732,8 +732,8 @@ static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) /* power up cec section */ adv7511_cec_write_and_or(sd, 0x4e, 0xfc, 0x01); /* legacy mode and clear all rx buffers */ + adv7511_cec_write(sd, 0x4a, 0x00); adv7511_cec_write(sd, 0x4a, 0x07); - adv7511_cec_write(sd, 0x4a, 0); adv7511_cec_write_and_or(sd, 0x11, 0xfe, 0); /* initially disable tx */ /* enabled irqs: */ /* tx: ready */ @@ -917,9 +917,6 @@ static void adv7511_set_isr(struct v4l2_subdev *sd, bool enable) else if (adv7511_have_hotplug(sd)) irqs |= MASK_ADV7511_EDID_RDY_INT; - adv7511_wr_and_or(sd, 0x95, 0xc0, - (state->cec_enabled_adap && enable) ? 0x39 : 0x00); - /* * This i2c write can fail (approx. 1 in 1000 writes). But it * is essential that this register is correct, so retry it @@ -933,9 +930,11 @@ static void adv7511_set_isr(struct v4l2_subdev *sd, bool enable) irqs_rd = adv7511_rd(sd, 0x94); } while (retries-- && irqs_rd != irqs); - if (irqs_rd == irqs) - return; - v4l2_err(sd, "Could not set interrupts: hw failure?\n"); + if (irqs_rd != irqs) + v4l2_err(sd, "Could not set interrupts: hw failure?\n"); + + adv7511_wr_and_or(sd, 0x95, 0xc0, + (state->cec_enabled_adap && enable) ? 0x39 : 0x00); } /* Interrupt handler */ @@ -982,8 +981,8 @@ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled) for (i = 0; i < msg.len; i++) msg.msg[i] = adv7511_cec_read(sd, i + 0x15); - adv7511_cec_write(sd, 0x4a, 1); /* toggle to re-enable rx 1 */ - adv7511_cec_write(sd, 0x4a, 0); + adv7511_cec_write(sd, 0x4a, 0); /* toggle to re-enable rx 1 */ + adv7511_cec_write(sd, 0x4a, 1); cec_received_msg(state->cec_adap, &msg); } } @@ -1778,6 +1777,7 @@ static void adv7511_init_setup(struct v4l2_subdev *sd) /* legacy mode */ adv7511_cec_write(sd, 0x4a, 0x00); + adv7511_cec_write(sd, 0x4a, 0x07); if (cec_clk % 75 != 0) v4l2_err(sd, "%s: cec_clk %d, not multiple of 750 Khz\n",
[PATCH] exynos4-is: Prevent NULL pointer dereference in __isp_video_try_fmt()
This patch fixes potential NULL pointer dereference as indicated by the following static checker warning: drivers/media/platform/exynos4-is/fimc-isp-video.c:408 isp_video_try_fmt_mplane() error: NULL dereference inside function '__isp_video_try_fmt(isp, &f->fmt.pix_mp, (0))()'. Fixes: 34947b8aebe3: ("[media] exynos4-is: Add the FIMC-IS ISP capture DMA driver") Reported-by: Dan Carpenter Signed-off-by: Sylwester Nawrocki --- drivers/media/platform/exynos4-is/fimc-isp-video.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 55ba696b8cf4..a920164f53f1 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -384,12 +384,17 @@ static void __isp_video_try_fmt(struct fimc_isp *isp, struct v4l2_pix_format_mplane *pixm, const struct fimc_fmt **fmt) { - *fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, 2); + const struct fimc_fmt *__fmt; + + __fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, 2); + + if (fmt) + *fmt = __fmt; pixm->colorspace = V4L2_COLORSPACE_SRGB; pixm->field = V4L2_FIELD_NONE; - pixm->num_planes = (*fmt)->memplanes; - pixm->pixelformat = (*fmt)->fourcc; + pixm->num_planes = __fmt->memplanes; + pixm->pixelformat = __fmt->fourcc; /* * TODO: double check with the docmentation these width/height * constraints are correct. -- 2.14.2
Re: [PATCH v16 0/2] rcar-csi2: add Renesas R-Car MIPI CSI-2
On Tue, May 15, 2018 at 07:50:45AM +0300, Laurent Pinchart wrote: > Hi Niklas, > > On Tuesday, 15 May 2018 03:56:33 EEST Niklas Söderlund wrote: > > Hi, > > > > This is the latest incarnation of R-Car MIPI CSI-2 receiver driver. It's > > based on top of the media-tree and are tested on Renesas Salvator-X and > > Salvator-XS together with adv7482 and the now in tree rcar-vin driver :-) > > > > I hope this is the last incarnation of this patch-set, I do think it is > > ready for upstream consumption :-) > > So do I. Even though you dropped Hans' reviewed-by tag due to changes in the > hardware initialization code, I think the part that Hans cares about the most > is the V4L2 API implementation, so I believe his review still applies. In my > opinion the series has received the necessary review. > > Hans, would you like to take this through your tree, or should we send a pull > request directly to Mauro ? I'd like the two patches to be merged in v4.18 if > possible. I've applied the patches to my tree as discussed with Hans previously. -- Sakari Ailus sakari.ai...@linux.intel.com
Re: [PATCH v2 2/2] rcar-vin: fix crop and compose handling for Gen3
Hi Niklas, This looks like quite the improvement :D On 11/05/18 15:41, Niklas Söderlund wrote: > When refactoring the Gen3 enablement series crop and compose handling > where broken. This went unnoticed but can result in writing out side the As well as Sergei's 'where/were', 'out side' is one word in this context. 'outside of the capture buffer' > capture buffer. Fix this by restoring the crop and compose to reflect > the format dimensions as we have not yet enabled the scaler for Gen3. > > Fixes: 5e7c623632fcf8f5 ("media: rcar-vin: use different v4l2 operations in > media controller mode") > Reported-by: Jacopo Mondi > Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham > --- > drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c > b/drivers/media/platform/rcar-vin/rcar-v4l2.c > index 2fb8587116f25a4f..e78fba84d59028ef 100644 > --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c > +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c > @@ -702,6 +702,12 @@ static int rvin_mc_s_fmt_vid_cap(struct file *file, void > *priv, > > vin->format = f->fmt.pix; > > + vin->crop.top = 0; > + vin->crop.left = 0; > + vin->crop.width = vin->format.width; > + vin->crop.height = vin->format.height; > + vin->compose = vin->crop; > + > return 0; > } > >
Re: [PATCH] media: helene: add I2C device probe function
Hi Katsuhiro, I love your patch! Perhaps something to improve: [auto build test WARNING on linuxtv-media/master] [also build test WARNING on v4.17-rc5 next-20180514] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Katsuhiro-Suzuki/media-helene-add-I2C-device-probe-function/20180515-134502 base: git://linuxtv.org/media_tree.git master reproduce: make htmldocs All warnings (new ones prefixed by >>): include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > include/net/mac80211.h:2083: warning: bad line: > net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg.signal' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'rx_stats_avg.chain_signal' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.filtered' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.retry_failed' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.retry_count' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.lost_packets' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_tdls_pkt_time' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.msdu_retries' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.msdu_failed' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_ack' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.last_ack_signal' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'status_stats.ack_signal_filled' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.packets' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.bytes' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.last_rate' not described in 'sta_info' net/mac80211/sta_info.h:586: warning: Function parameter or member 'tx_stats.msdu' not described in 'sta_info' kernel/sched/fair.c:3731: warning: Function parameter or member 'flags' not described in 'attach_entity_load_avg' include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.cb' not described in 'dma_buf' include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.poll' not described in 'dma_buf' include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.active' not described in 'dma_buf' include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.cb' not described in 'dma_buf' include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.poll' not described in 'dma_buf
Re: [PATCH v2 1/2] Revert "media: rcar-vin: enable field toggle after a set number of lines for Gen3"
Hi Niklas, On 11/05/18 15:41, Niklas Söderlund wrote: > The offending commit was an attempt to fix the issue of writing outside > the capture buffer for VIN Gen3. Unfortunately it only fixed the symptom > of the problem to such a degree I could no longer reproduce it. Revert > the offending commit before a proper fix can be added in a follow-up > patch. > > This reverts commit 015060cb7795eac34454696cc9c9f8b76926a401. > > Signed-off-by: Niklas Söderlund Acked-by: Kieran Bingham > --- > drivers/media/platform/rcar-vin/rcar-dma.c | 20 +--- > 1 file changed, 5 insertions(+), 15 deletions(-) > > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c > b/drivers/media/platform/rcar-vin/rcar-dma.c > index b41ba9a4a2b3ac90..ac07f99e3516a620 100644 > --- a/drivers/media/platform/rcar-vin/rcar-dma.c > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c > @@ -124,9 +124,7 @@ > #define VNDMR2_VPS (1 << 30) > #define VNDMR2_HPS (1 << 29) > #define VNDMR2_FTEV (1 << 17) > -#define VNDMR2_FTEH (1 << 16) > #define VNDMR2_VLV(n)((n & 0xf) << 12) > -#define VNDMR2_HLV(n)((n) & 0xfff) > > /* Video n CSI2 Interface Mode Register (Gen3) */ > #define VNCSI_IFMD_DES1 (1 << 26) > @@ -614,9 +612,8 @@ void rvin_crop_scale_comp(struct rvin_dev *vin) > > static int rvin_setup(struct rvin_dev *vin) > { > - u32 vnmc, dmr, dmr2, interrupts, lines; > + u32 vnmc, dmr, dmr2, interrupts; > bool progressive = false, output_is_yuv = false, input_is_yuv = false; > - bool halfsize = false; > > switch (vin->format.field) { > case V4L2_FIELD_TOP: > @@ -631,15 +628,12 @@ static int rvin_setup(struct rvin_dev *vin) > /* Use BT if video standard can be read and is 60 Hz format */ > if (!vin->info->use_mc && vin->std & V4L2_STD_525_60) > vnmc = VNMC_IM_FULL | VNMC_FOC; > - halfsize = true; > break; > case V4L2_FIELD_INTERLACED_TB: > vnmc = VNMC_IM_FULL; > - halfsize = true; > break; > case V4L2_FIELD_INTERLACED_BT: > vnmc = VNMC_IM_FULL | VNMC_FOC; > - halfsize = true; > break; > case V4L2_FIELD_NONE: > vnmc = VNMC_IM_ODD_EVEN; > @@ -682,15 +676,11 @@ static int rvin_setup(struct rvin_dev *vin) > break; > } > > - if (vin->info->model == RCAR_GEN3) { > - /* Enable HSYNC Field Toggle mode after height HSYNC inputs. */ > - lines = vin->format.height / (halfsize ? 2 : 1); > - dmr2 = VNDMR2_FTEH | VNDMR2_HLV(lines); > - vin_dbg(vin, "Field Toogle after %u lines\n", lines); > - } else { > - /* Enable VSYNC Field Toogle mode after one VSYNC input. */ > + /* Enable VSYNC Field Toogle mode after one VSYNC input */ > + if (vin->info->model == RCAR_GEN3) > + dmr2 = VNDMR2_FTEV; > + else > dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); > - } > > /* Hsync Signal Polarity Select */ > if (!(vin->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) >
Re: [PATCH v2 27/29] venus: implementing multi-stream support
Hi Hans, On 05/15/2018 11:17 AM, Hans Verkuil wrote: > Hi Stanimir, > > On 05/15/18 09:58, Stanimir Varbanov wrote: >> This is implementing a multi-stream decoder support. The multi >> stream gives an option to use the secondary decoder output >> with different raw format (or the same in case of crop). > > You told me that multi-stream support is currently internal only. > > It would be good if you could elaborate a bit about that in this > commit log and (I think) also add some comments in the code that > reflect this. > > It's also not clear to me how and why this is used in the driver > if this is just internal. Does it enable a feature you would > otherwise not be able to use? > > I have no complaints about the code, I would just like to see a > bit more background information in the source and commit log. Thanks for the fast comments! Sure I will try to document multi-stream support in the patch description and in the code if it makes sense. -- regards, Stan
Re: [PATCH 27/61] media: platform: s5p-mfc: simplify getting .drvdata
On 04/19/2018 04:05 PM, Wolfram Sang wrote: > We should get drvdata from struct device directly. Going via > platform_device is an unneeded step back and forth. > > Signed-off-by: Wolfram Sang Acked-by: Sylwester Nawrocki
Re: [PATCH 26/61] media: platform: exynos4-is: simplify getting .drvdata
On 04/19/2018 04:05 PM, Wolfram Sang wrote: > We should get drvdata from struct device directly. Going via > platform_device is an unneeded step back and forth. > > Signed-off-by: Wolfram Sang Acked-by: Sylwester Nawrocki
[PATCH v2] media: dvb-frontends: add Socionext SC1501A ISDB-S/T demodulator driver
This patch adds a frontend driver for the Socionext SC1501A series and Socionext MN88443x ISDB-S/T demodulators. Signed-off-by: Katsuhiro Suzuki --- Changes since v1: - Fix sparse warning about type of constant - Use div_s64() instead of divide operator --- drivers/media/dvb-frontends/Kconfig | 10 + drivers/media/dvb-frontends/Makefile | 1 + drivers/media/dvb-frontends/sc1501a.c | 802 ++ drivers/media/dvb-frontends/sc1501a.h | 27 + 4 files changed, 840 insertions(+) create mode 100644 drivers/media/dvb-frontends/sc1501a.c create mode 100644 drivers/media/dvb-frontends/sc1501a.h diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 55e36a4f5215..e9d2c94b290e 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -739,6 +739,16 @@ config DVB_TC90522 Toshiba TC90522 2xISDB-S 8PSK + 2xISDB-T OFDM demodulator. Say Y when you want to support this frontend. +config DVB_SC1501A + tristate "Socionext SC1501A" + depends on DVB_CORE && I2C + select REGMAP_I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + A driver for Socionext SC1501A and Panasonic MN88443x + ISDB-S + ISDB-T demodulator. + Say Y when you want to support this frontend. + comment "Digital terrestrial only tuners/PLL" depends on DVB_CORE diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index 67a783fd5ed0..e204502347ed 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -125,6 +125,7 @@ obj-$(CONFIG_DVB_AF9033) += af9033.o obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o obj-$(CONFIG_DVB_GP8PSK_FE) += gp8psk-fe.o obj-$(CONFIG_DVB_TC90522) += tc90522.o +obj-$(CONFIG_DVB_SC1501A) += sc1501a.o obj-$(CONFIG_DVB_HORUS3A) += horus3a.o obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o obj-$(CONFIG_DVB_HELENE) += helene.o diff --git a/drivers/media/dvb-frontends/sc1501a.c b/drivers/media/dvb-frontends/sc1501a.c new file mode 100644 index ..c3d0369a9448 --- /dev/null +++ b/drivers/media/dvb-frontends/sc1501a.c @@ -0,0 +1,802 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Socionext SC1501A series demodulator driver for ISDB-S/ISDB-T. +// +// Copyright (c) 2018 Socionext Inc. + +#include +#include +#include +#include +#include +#include +#include + +#include "sc1501a.h" + +/* ISDB-S registers */ +#define ATSIDU_S0x2f +#define ATSIDL_S0x30 +#define TSSET_S 0x31 +#define AGCREAD_S 0x5a +#define CPMON1_S0x5e +#define CPMON1_S_FSYNC BIT(5) +#define CPMON1_S_ERRMON BIT(4) +#define CPMON1_S_SIGOFF BIT(3) +#define CPMON1_S_W2LOCK BIT(2) +#define CPMON1_S_W1LOCK BIT(1) +#define CPMON1_S_DW1LOCKBIT(0) +#define TRMON_S 0x60 +#define BERCNFLG_S 0x68 +#define BERCNFLG_S_BERVRDY BIT(5) +#define BERCNFLG_S_BERVCHK BIT(4) +#define BERCNFLG_S_BERDRDY BIT(3) +#define BERCNFLG_S_BERDCHK BIT(2) +#define CNRDXU_S0x69 +#define CNRDXL_S0x6a +#define CNRDYU_S0x6b +#define CNRDYL_S0x6c +#define BERVRDU_S 0x71 +#define BERVRDL_S 0x72 +#define DOSET1_S0x73 + +/* Primary ISDB-T */ +#define PLLASET10x00 +#define PLLASET20x01 +#define PLLBSET10x02 +#define PLLBSET20x03 +#define PLLSET 0x04 +#define OUTCSET 0x08 +#define OUTCSET_CHDRV_8MA 0xff +#define OUTCSET_CHDRV_4MA 0x00 +#define PLDWSET 0x09 +#define PLDWSET_NORMAL 0x00 +#define PLDWSET_PULLDOWN 0xff +#define HIZSET1 0x0a +#define HIZSET2 0x0b + +/* Secondary ISDB-T (for MN884434 only) */ +#define RCVSET 0x00 +#define TSSET1_M0x01 +#define TSSET2_M0x02 +#define TSSET3_M0x03 +#define INTACSET
Re: [PATCH 3/7] s5p-mfc: fix two sparse warnings
On 05/14/2018 03:13 PM, Hans Verkuil wrote: > From: Hans Verkuil > > media-git/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c: In function > 'vidioc_querycap': > media-git/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c:1317:2: warning: > 'strncpy' output may be truncated copying 31 bytes from a string of length 31 > [-Wstringop-truncation] > strncpy(cap->card, dev->vfd_enc->name, sizeof(cap->card) - 1); > ^ > media-git/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c: In function > 'vidioc_querycap': > media-git/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c:275:2: warning: > 'strncpy' output may be truncated copying 31 bytes from a string of length 31 > [-Wstringop-truncation] > strncpy(cap->card, dev->vfd_dec->name, sizeof(cap->card) - 1); > ^ > > Signed-off-by: Hans Verkuil Acked-by: Sylwester Nawrocki
Re: [PATCH v2 7/7] media: via-camera: allow build on non-x86 archs with COMPILE_TEST
On Friday, May 04, 2018 04:24:15 PM Bartlomiej Zolnierkiewicz wrote: > On Friday, May 04, 2018 11:07:01 AM Mauro Carvalho Chehab wrote: > > Em Mon, 23 Apr 2018 14:19:31 +0200 > > Bartlomiej Zolnierkiewicz escreveu: > > > > > > > How's about just allowing COMPILE_TEST for FB_VIA instead of adding > > > all these stubs? > > > > Works for me. > > > > Do you want to apply it via your tree or via the media one? > > > > If you prefer to apply on yours: > > > > Reviewed-by: Mauro Carvalho Chehab > > Thanks, I'll apply it to my tree later. I've queued the patch for v4.18 now. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics
Re: Are media drivers abusing of GFP_DMA? - was: Re: [LSF/MM TOPIC NOTES] x86 ZONE_DMA love
Hi Laurent, Em Tue, 15 May 2018 11:27:44 +0300 Laurent Pinchart escreveu: > Hello, > > On Tuesday, 15 May 2018 10:30:28 EEST Fabien DESSENNE wrote: > > On 14/05/18 12:39, Mauro Carvalho Chehab wrote: > > > Em Mon, 14 May 2018 07:35:03 -0300 Mauro Carvalho Chehab escreveu: > > >> Em Mon, 14 May 2018 08:00:37 + Fabien DESSENNE escreveu: > > >>> On 07/05/18 17:19, Mauro Carvalho Chehab wrote: > > Em Mon, 07 May 2018 16:26:08 +0300 Laurent Pinchart escreveu: > > > On Saturday, 5 May 2018 19:08:15 EEST Mauro Carvalho Chehab wrote: > > > > > >> There was a recent discussion about the use/abuse of GFP_DMA flag > > >> when allocating memories at LSF/MM 2018 (see Luis notes enclosed). > > >> > > >> The idea seems to be to remove it, using CMA instead. Before doing > > >> that, better to check if what we have on media is are valid use cases > > >> for it, or if it is there just due to some misunderstanding (or > > >> because it was copied from some other code). > > >> > > >> Hans de Goede sent us today a patch stopping abuse at gspca, and I'm > > >> also posting today two other patches meant to stop abuse of it on > > >> USB drivers. Still, there are 4 platform drivers using it: > > >> > > >> $ git grep -l -E "GFP_DMA\\b" drivers/media/ > > >> drivers/media/platform/omap3isp/ispstat.c > > >> drivers/media/platform/sti/bdisp/bdisp-hw.c > > >> drivers/media/platform/sti/hva/hva-mem.c > > >>> > > >>> The two STI drivers (bdisp-hw.c and hva-mem.c) are only expected to run > > >>> on ARM platforms, not on x86. Since this thread deals with x86 & DMA > > >>> trouble, I am not sure that we actually have a problem for the sti > > >>> drivers. > > >>> > > >>> There are some other sti drivers that make use of this GFP_DMA flag > > >>> (drivers/gpu/drm/sti/sti_*.c) and it does not seem to be a problem. > > >>> > > >>> Nevertheless I can see that the media sti drivers depend on COMPILE_TEST > > >>> (which is not the case for the DRM ones). > > >>> Would it be an acceptable solution to remove the COMPILE_TEST > > >>> dependency? > > >> > > >> This has nothing to do with either x86 or COMPILE_TEST. The thing is > > >> that there's a plan for removing GFP_DMA from the Kernel[1], as it was > > >> originally meant to be used only by old PCs, where the DMA controllers > > >> used only on the bottom 16 MB memory address (24 bits). IMHO, it is > > >> very unlikely that any ARM SoC have such limitation. > > >> > > >> [1] https://lwn.net/Articles/753273/ (article will be freely available > > >> on May, 17) > > > > > > Btw, you can also read about that at: > > > > > > https://lwn.net/Articles/753274/ > > > > > >> Anyway, before the removal of GFP_DMA happens, I'd like to better > > >> understand why we're using it at media, and if we can, instead, > > >> set the DMA bit mask, just like almost all other media drivers > > >> that require to confine DMA into a certain range do. In the case > > >> of ARM, this is what we currently have: > > >> > > >> drivers/media/platform/exynos-gsc/gsc-core.c: > > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > > >> drivers/media/platform/exynos4-is/fimc-core.c: > > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > > >> drivers/media/platform/exynos4-is/fimc-is.c: > > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > > >> drivers/media/platform/exynos4-is/fimc-lite.c: > > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > > >> drivers/media/platform/mtk-mdp/mtk_mdp_core.c: > > >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); > > >> drivers/media/platform/omap3isp/isp.c: ret = > > >> dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); > > >> drivers/media/platform/s5p-g2d/g2d.c: > > >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); > > >> drivers/media/platform/s5p-jpeg/jpeg-core.c: > > >> vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); > > >> drivers/media/platform/s5p-mfc/s5p_mfc.c: > > >>DMA_BIT_MASK(32)); > > >> drivers/media/platform/s5p-mfc/s5p_mfc.c: > > >> DMA_BIT_MASK(32)); > > >> drivers/media/platform/s5p-mfc/s5p_mfc.c: > > >> vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > > > > That's clearer now, thank you for the clarification > > I am about to send patches for the sti drivers (set the DMA bit mask) > > Some drivers call vb2_dma_contig_set_max_seg_size() and some call > dma_coerce_mask_and_coherent(). Both are likely needed, the former telling > the > DMA mapping API about the maximum size of a scatter-gather chunk that the > device supports (when using vb2-dma-contig that size should really be the > full > address space supported by the device as we want DMA-contiguous buffers), and > the latter telling the DMA mapping API about the address space th
Re: [PATCH v1 1/4] media: rc: introduce BPF_PROG_IR_DECODER
On Mon, May 14, 2018 at 09:48:05PM -0700, Y Song wrote: > On Mon, May 14, 2018 at 2:10 PM, Sean Young wrote: > > Add support for BPF_PROG_IR_DECODER. This type of BPF program can call > > rc_keydown() to reported decoded IR scancodes, or rc_repeat() to report > > that the last key should be repeated. > > > > Signed-off-by: Sean Young > > --- > > drivers/media/rc/Kconfig | 8 +++ > > drivers/media/rc/Makefile | 1 + > > drivers/media/rc/ir-bpf-decoder.c | 93 +++ > > include/linux/bpf_types.h | 3 + > > include/uapi/linux/bpf.h | 16 +- > > 5 files changed, 120 insertions(+), 1 deletion(-) > > create mode 100644 drivers/media/rc/ir-bpf-decoder.c > > > > diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig > > index eb2c3b6eca7f..10ad6167d87c 100644 > > --- a/drivers/media/rc/Kconfig > > +++ b/drivers/media/rc/Kconfig > > @@ -120,6 +120,14 @@ config IR_IMON_DECODER > >remote control and you would like to use it with a raw IR > >receiver, or if you wish to use an encoder to transmit this IR. > > > > +config IR_BPF_DECODER > > + bool "Enable IR raw decoder using BPF" > > + depends on BPF_SYSCALL > > + depends on RC_CORE=y > > + help > > + Enable this option to make it possible to load custom IR > > + decoders written in BPF. > > + > > endif #RC_DECODERS > > > > menuconfig RC_DEVICES > > diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile > > index 2e1c87066f6c..12e1118430d0 100644 > > --- a/drivers/media/rc/Makefile > > +++ b/drivers/media/rc/Makefile > > @@ -5,6 +5,7 @@ obj-y += keymaps/ > > obj-$(CONFIG_RC_CORE) += rc-core.o > > rc-core-y := rc-main.o rc-ir-raw.o > > rc-core-$(CONFIG_LIRC) += lirc_dev.o > > +rc-core-$(CONFIG_IR_BPF_DECODER) += ir-bpf-decoder.o > > obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o > > obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o > > obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o > > diff --git a/drivers/media/rc/ir-bpf-decoder.c > > b/drivers/media/rc/ir-bpf-decoder.c > > new file mode 100644 > > index ..aaa5e208b1a5 > > --- /dev/null > > +++ b/drivers/media/rc/ir-bpf-decoder.c > > @@ -0,0 +1,93 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +// ir-bpf-decoder.c - handles bpf decoders > > +// > > +// Copyright (C) 2018 Sean Young > > + > > +#include > > +#include > > +#include "rc-core-priv.h" > > + > > +/* > > + * BPF interface for raw IR decoder > > + */ > > +const struct bpf_prog_ops ir_decoder_prog_ops = { > > +}; > > + > > +BPF_CALL_1(bpf_rc_repeat, struct ir_raw_event*, event) > > +{ > > + struct ir_raw_event_ctrl *ctrl; > > + > > + ctrl = container_of(event, struct ir_raw_event_ctrl, prev_ev); > > + > > + rc_repeat(ctrl->dev); > > + return 0; > > +} > > + > > +static const struct bpf_func_proto rc_repeat_proto = { > > + .func = bpf_rc_repeat, > > + .gpl_only = true, // rc_repeat is EXPORT_SYMBOL_GPL > > + .ret_type = RET_VOID, > > I suggest using RET_INTEGER here since we do return an integer 0. > RET_INTEGER will also make it easy to extend if you want to return > a non-zero value for error code or other reasons. Ok. > > + .arg1_type = ARG_PTR_TO_CTX, > > +}; > > + > > +BPF_CALL_4(bpf_rc_keydown, struct ir_raw_event*, event, u32, protocol, > > + u32, scancode, u32, toggle) > > +{ > > + struct ir_raw_event_ctrl *ctrl; > > + > > + ctrl = container_of(event, struct ir_raw_event_ctrl, prev_ev); > > + rc_keydown(ctrl->dev, protocol, scancode, toggle != 0); > > + return 0; > > +} > > + > > +static const struct bpf_func_proto rc_keydown_proto = { > > + .func = bpf_rc_keydown, > > + .gpl_only = true, // rc_keydown is EXPORT_SYMBOL_GPL > > + .ret_type = RET_VOID, > > ditto. RET_INTEGER is preferable. Ok. > > + .arg1_type = ARG_PTR_TO_CTX, > > + .arg2_type = ARG_ANYTHING, > > + .arg3_type = ARG_ANYTHING, > > + .arg4_type = ARG_ANYTHING, > > +}; > > + > > +static const struct bpf_func_proto *ir_decoder_func_proto(enum bpf_func_id > > func_id, const struct bpf_prog *prog) > > +{ > > + switch (func_id) { > > + case BPF_FUNC_rc_repeat: > > + return &rc_repeat_proto; > > + case BPF_FUNC_rc_keydown: > > + return &rc_keydown_proto; > > + case BPF_FUNC_map_lookup_elem: > > + return &bpf_map_lookup_elem_proto; > > + case BPF_FUNC_map_update_elem: > > + return &bpf_map_update_elem_proto; > > + case BPF_FUNC_map_delete_elem: > > + return &bpf_map_delete_elem_proto; > > + case BPF_FUNC_ktime_get_ns: > > + return &bpf_ktime_get_ns_proto; > > + case BPF_FUNC_tail_call: > > + return &bpf_tail_call_proto; > > + case BPF_FUNC_get_prandom_u32: > > + return &bpf_get_prandom_u32_proto; > > + def
Re: [PATCH v1 4/4] samples/bpf: an example of a raw IR decoder
On Mon, May 14, 2018 at 10:34:57PM -0700, Y Song wrote: > On Mon, May 14, 2018 at 2:11 PM, Sean Young wrote: > > This implements the grundig-16 IR protocol. > > > > Signed-off-by: Sean Young > > --- > > samples/bpf/Makefile | 4 + > > samples/bpf/bpf_load.c| 9 +- > > samples/bpf/grundig_decoder_kern.c| 112 ++ > > samples/bpf/grundig_decoder_user.c| 54 +++ > > tools/bpf/bpftool/prog.c | 1 + > > tools/include/uapi/linux/bpf.h| 17 +++- > > tools/testing/selftests/bpf/bpf_helpers.h | 6 ++ > > 7 files changed, 200 insertions(+), 3 deletions(-) > > create mode 100644 samples/bpf/grundig_decoder_kern.c > > create mode 100644 samples/bpf/grundig_decoder_user.c > > > > diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile > > index 4d6a6edd4bf6..c6fa111f103a 100644 > > --- a/samples/bpf/Makefile > > +++ b/samples/bpf/Makefile > > @@ -44,6 +44,7 @@ hostprogs-y += xdp_monitor > > hostprogs-y += xdp_rxq_info > > hostprogs-y += syscall_tp > > hostprogs-y += cpustat > > +hostprogs-y += grundig_decoder > > > > # Libbpf dependencies > > LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o > > @@ -95,6 +96,7 @@ xdp_monitor-objs := bpf_load.o $(LIBBPF) > > xdp_monitor_user.o > > xdp_rxq_info-objs := bpf_load.o $(LIBBPF) xdp_rxq_info_user.o > > syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o > > cpustat-objs := bpf_load.o $(LIBBPF) cpustat_user.o > > +grundig_decoder-objs := bpf_load.o $(LIBBPF) grundig_decoder_user.o > > > > # Tell kbuild to always build the programs > > always := $(hostprogs-y) > > @@ -148,6 +150,7 @@ always += xdp_rxq_info_kern.o > > always += xdp2skb_meta_kern.o > > always += syscall_tp_kern.o > > always += cpustat_kern.o > > +always += grundig_decoder_kern.o > > > > HOSTCFLAGS += -I$(objtree)/usr/include > > HOSTCFLAGS += -I$(srctree)/tools/lib/ > > @@ -193,6 +196,7 @@ HOSTLOADLIBES_xdp_monitor += -lelf > > HOSTLOADLIBES_xdp_rxq_info += -lelf > > HOSTLOADLIBES_syscall_tp += -lelf > > HOSTLOADLIBES_cpustat += -lelf > > +HOSTLOADLIBES_grundig_decoder += -lelf > > > > # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine > > on cmdline: > > # make samples/bpf/ LLC=~/git/llvm/build/bin/llc > > CLANG=~/git/llvm/build/bin/clang > > diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c > > index bebe4188b4b3..0fd389e95bb9 100644 > > --- a/samples/bpf/bpf_load.c > > +++ b/samples/bpf/bpf_load.c > > @@ -69,6 +69,7 @@ static int load_and_attach(const char *event, struct > > bpf_insn *prog, int size) > > bool is_sockops = strncmp(event, "sockops", 7) == 0; > > bool is_sk_skb = strncmp(event, "sk_skb", 6) == 0; > > bool is_sk_msg = strncmp(event, "sk_msg", 6) == 0; > > + bool is_ir_decoder = strncmp(event, "ir_decoder", 10) == 0; > > size_t insns_cnt = size / sizeof(struct bpf_insn); > > enum bpf_prog_type prog_type; > > char buf[256]; > > @@ -102,6 +103,8 @@ static int load_and_attach(const char *event, struct > > bpf_insn *prog, int size) > > prog_type = BPF_PROG_TYPE_SK_SKB; > > } else if (is_sk_msg) { > > prog_type = BPF_PROG_TYPE_SK_MSG; > > + } else if (is_ir_decoder) { > > + prog_type = BPF_PROG_TYPE_RAWIR_DECODER; > > } else { > > printf("Unknown event '%s'\n", event); > > return -1; > > @@ -116,7 +119,8 @@ static int load_and_attach(const char *event, struct > > bpf_insn *prog, int size) > > > > prog_fd[prog_cnt++] = fd; > > > > - if (is_xdp || is_perf_event || is_cgroup_skb || is_cgroup_sk) > > + if (is_xdp || is_perf_event || is_cgroup_skb || is_cgroup_sk || > > + is_ir_decoder) > > return 0; > > > > if (is_socket || is_sockops || is_sk_skb || is_sk_msg) { > > @@ -607,7 +611,8 @@ static int do_load_bpf_file(const char *path, > > fixup_map_cb fixup_map) > > memcmp(shname, "cgroup/", 7) == 0 || > > memcmp(shname, "sockops", 7) == 0 || > > memcmp(shname, "sk_skb", 6) == 0 || > > - memcmp(shname, "sk_msg", 6) == 0) { > > + memcmp(shname, "sk_msg", 6) == 0 || > > + memcmp(shname, "ir_decoder", 10) == 0) { > > ret = load_and_attach(shname, data->d_buf, > > data->d_size); > > if (ret != 0) > > diff --git a/samples/bpf/grundig_decoder_kern.c > > b/samples/bpf/grundig_decoder_kern.c > > new file mode 100644 > > index ..c80f2c9cc69a > > --- /dev/null > > +++ b/samples/bpf/grundig_decoder_kern.c > > @@ -0,0 +1,112 @@ > > + > > +#include > > +#include > > +#include "bpf_helpers.h" > > +#include > > + > > +enum grundig_state { > > + STATE_INACTIVE, > > + STATE_HEADER_SPAC
Re: Charity Support
I Mikhail Fridman. has selected you specially as one of my beneficiaries for my Charitable Donation, Just as I have declared on May 23, 2016 to give my fortune as charity. Check the link below for confirmation: http://www.ibtimes.co.uk/russias-second-wealthiest-man-mikhail-fridman-plans-leaving-14-2bn-fortune-charity-1561604 Reply as soon as possible with further directives. Best Regards, Mikhail Fridman.
[PATCH] usbtv: Fix refcounting mixup
The premature free in the error path is blocked by V4L refcounting, not USB refcounting. Thanks to Ben Hutchings for review. Signed-off-by: Oliver Neukum Fixes: 50e704453553 ("media: usbtv: prevent double free in error case") --- drivers/media/usb/usbtv/usbtv-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c index 5095c380b2c1..4a03c4d66314 100644 --- a/drivers/media/usb/usbtv/usbtv-core.c +++ b/drivers/media/usb/usbtv/usbtv-core.c @@ -113,7 +113,8 @@ static int usbtv_probe(struct usb_interface *intf, usbtv_audio_fail: /* we must not free at this point */ - usb_get_dev(usbtv->udev); + v4l2_device_get(&usbtv->v4l2_dev); + /* this will undo the v4l2_device_get() */ usbtv_video_free(usbtv); usbtv_video_fail: -- 2.13.6
Re: [PATCH 01/11] media: tm6000: fix potential Spectre variant 1
Em Mon, 14 May 2018 22:31:37 -0500 "Gustavo A. R. Silva" escreveu: > Hi Mauro, > > On 04/26/2018 06:42 PM, Mauro Carvalho Chehab wrote: > > >> > >> I noticed you changed the status of this series from rejected to new. > > > > Yes. > > > >> Also, there are other similar issues in media/pci/ > > > > Well, the issues will be there everywhere on all media drivers. > > > > I marked your patches because I need to study it carefully, after > > Peter's explanations. My plan is to do it next week. Still not > > sure if the approach you took is the best one or not. > > > > As I said, one possibility is to change the way v4l2-core handles > > VIDIOC_ENUM_foo ioctls, but that would be make harder to -stable > > backports. > > > > I need a weekend to sleep on it. > > > > I'm curious about how you finally resolved to handle these issues. > > I noticed Smatch is no longer reporting them. There was no direct fix for it, but maybe this patch has something to do with the smatch error report cleanup: commit 3ad3b7a2ebaefae37a7eafed0779324987ca5e56 Author: Sami Tolvanen Date: Tue May 8 13:56:12 2018 -0400 media: v4l2-ioctl: replace IOCTL_INFO_STD with stub functions This change removes IOCTL_INFO_STD and adds stub functions where needed using the DEFINE_V4L_STUB_FUNC macro. This fixes indirect call mismatches with Control-Flow Integrity, caused by calling standard ioctls using a function pointer that doesn't match the function type. Signed-off-by: Sami Tolvanen Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab > > Thanks > -- > Gustavo Thanks, Mauro
Re: [PATCH] dma-fence: Make dma_fence_add_callback() fail if signaled with error
Quoting Ezequiel Garcia (2018-05-14 22:28:31) > On Mon, 2018-05-14 at 18:48 +0200, Daniel Vetter wrote: > > On Fri, May 11, 2018 at 08:27:41AM +0100, Chris Wilson wrote: > > > Quoting Ezequiel Garcia (2018-05-09 21:14:49) > > > > Change how dma_fence_add_callback() behaves, when the fence > > > > has error-signaled by the time it is being add. After this commit, > > > > dma_fence_add_callback() returns the fence error, if it > > > > has error-signaled before dma_fence_add_callback() is called. > > > > > > Why? What problem are you trying to solve? fence->error does not imply > > > that the fence has yet been signaled, and the caller wants a callback > > > when it is signaled. > > > > On top this is incosistent, e.g. we don't do the same for any of the other > > dma_fence interfaces. Plus there's the issue that you might alias errno > > values with fence errno values. > > > > Right. > > > I think keeping the error codes from the functions you're calling distinct > > from the error code of the fence itself makes a lot of sense. The first > > tells you whether your request worked out (or why not), the second tells > > you whether the asynchronous dma operation (gpu rendering, page flip, > > whatever) that the dma_fence represents worked out (or why not). That's 2 > > distinct things imo. > > > > Might be good to show us the driver code that needs this behaviour so we > > can discuss how to best handle your use-case. > > > > This change arose while discussing the in-fences support for video4linux. > Here's the patch that calls dma_fence_add_callback > https://lkml.org/lkml/2018/5/4/766. > > The code snippet currently looks something like this: > > if (vb->in_fence) { > ret = dma_fence_add_callback(vb->in_fence, &vb->fence_cb, > > vb2_qbuf_fence_cb); > /* is the fence signaled? */ > if (ret == -ENOENT) { > > dma_fence_put(vb->in_fence); > vb->in_fence = NULL; > } else if (ret) > { > goto unlock; > } > } > > In this use case, if the callback is added successfully, > the video4linux core defers the activation of the buffer > until the fence signals. > > If the fence is signaled (currently disregarding of errors) > then the buffer is assumed to be ready to be activated, > and so it gets queued for hardware usage. > > Giving some more thought to this, I'm not so sure what is > the right action if a fence signaled with error. In this case, > it appears to me that we shouldn't be using this buffer > if its in-fence is in error, but perhaps I'm missing > something. What I have in mind for async errors is to skip the operation and propagate the error onto the next fence. Mostly because those async errors may include fatal errors such as unable to pin the backing storage for the operation, but even "trivial" errors such as an early operation failing means that this request is then subject to garbage-in, garbage-out. However, for trivial errors I would just propagate the error status (so the caller knows something went wrong if they care, but in all likelihood no one will notice) and continue on with the glitchy operation. -Chris
Re: [PATCH v1 1/4] media: rc: introduce BPF_PROG_IR_DECODER
On Mon, May 14, 2018 at 04:27:19PM -0700, Randy Dunlap wrote: > On 05/14/2018 02:10 PM, Sean Young wrote: > > Add support for BPF_PROG_IR_DECODER. This type of BPF program can call > > Kconfig file below uses IR_BPF_DECODER instead of the symbol name above. > > and then patch 3 says a third choice: > The context provided to a BPF_PROG_RAWIR_DECODER is a struct ir_raw_event; Yes, you're right. I guess the source/trigger is raw IR events; decoding is something you're likely to do, but not necessarily. So: bpf type: BPF_PROG_TYPE_RAWIR_EVENT, has context struct bpf_rawir_event. Then we can call the Kconfig option CONFIG_BPF_RAW_IR_EVENT Sean > > > rc_keydown() to reported decoded IR scancodes, or rc_repeat() to report > > that the last key should be repeated. > > > > Signed-off-by: Sean Young > > --- > > drivers/media/rc/Kconfig | 8 +++ > > drivers/media/rc/Makefile | 1 + > > drivers/media/rc/ir-bpf-decoder.c | 93 +++ > > include/linux/bpf_types.h | 3 + > > include/uapi/linux/bpf.h | 16 +- > > 5 files changed, 120 insertions(+), 1 deletion(-) > > create mode 100644 drivers/media/rc/ir-bpf-decoder.c > > > > diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig > > index eb2c3b6eca7f..10ad6167d87c 100644 > > --- a/drivers/media/rc/Kconfig > > +++ b/drivers/media/rc/Kconfig > > @@ -120,6 +120,14 @@ config IR_IMON_DECODER > >remote control and you would like to use it with a raw IR > >receiver, or if you wish to use an encoder to transmit this IR. > > > > +config IR_BPF_DECODER > > + bool "Enable IR raw decoder using BPF" > > + depends on BPF_SYSCALL > > + depends on RC_CORE=y > > + help > > + Enable this option to make it possible to load custom IR > > + decoders written in BPF. > > + > > endif #RC_DECODERS > > > > menuconfig RC_DEVICES > > diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile > > index 2e1c87066f6c..12e1118430d0 100644 > > --- a/drivers/media/rc/Makefile > > +++ b/drivers/media/rc/Makefile > > @@ -5,6 +5,7 @@ obj-y += keymaps/ > > obj-$(CONFIG_RC_CORE) += rc-core.o > > rc-core-y := rc-main.o rc-ir-raw.o > > rc-core-$(CONFIG_LIRC) += lirc_dev.o > > +rc-core-$(CONFIG_IR_BPF_DECODER) += ir-bpf-decoder.o > > > -- > ~Randy
[PATCH] media: dvb_ca_en50221: prevent using slot_info for Spectre attacs
slot can be controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability, as warned by smatch: drivers/media/dvb-core/dvb_ca_en50221.c:1479 dvb_ca_en50221_io_write() warn: potential spectre issue 'ca->slot_info' (local cap) Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 97365a863519..1310526b0d49 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1476,6 +1477,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, if (slot >= ca->slot_count) return -EINVAL; + slot = array_index_nospec(slot, ca->slot_count); sl = &ca->slot_info[slot]; /* check if the slot is actually running */ -- 2.17.0
[PATCH 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.
The EC can expose a CEC bus, this patch adds the CEC related definitions needed by the cros-ec-cec driver. Having a 16 byte mkbp event size makes it possible to send CEC messages from the EC to the AP directly inside the mkbp event instead of first doing a notification and then a read. Signed-off-by: Stefan Adolfsson Signed-off-by: Neil Armstrong --- drivers/platform/chrome/cros_ec_proto.c | 42 + include/linux/mfd/cros_ec.h | 2 +- include/linux/mfd/cros_ec_commands.h| 80 + 3 files changed, 114 insertions(+), 10 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index e7bbdf9..ba47f79 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -504,29 +504,53 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, } EXPORT_SYMBOL(cros_ec_cmd_xfer_status); +static int get_next_event_xfer(struct cros_ec_device *ec_dev, + struct cros_ec_command *msg, + int version, uint32_t size) +{ + int ret; + + msg->version = version; + msg->command = EC_CMD_GET_NEXT_EVENT; + msg->insize = size; + msg->outsize = 0; + + ret = cros_ec_cmd_xfer(ec_dev, msg); + if (ret > 0) { + ec_dev->event_size = ret - 1; + memcpy(&ec_dev->event_data, msg->data, size); + } + + return ret; +} + static int get_next_event(struct cros_ec_device *ec_dev) { u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)]; struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; + static int cmd_version = 1; int ret; + BUILD_BUG_ON(sizeof(union ec_response_get_next_data_v1) != 16); + if (ec_dev->suspended) { dev_dbg(ec_dev->dev, "Device suspended.\n"); return -EHOSTDOWN; } - msg->version = 0; - msg->command = EC_CMD_GET_NEXT_EVENT; - msg->insize = sizeof(ec_dev->event_data); - msg->outsize = 0; + if (cmd_version == 1) { + ret = get_next_event_xfer(ec_dev, msg, cmd_version, + sizeof(ec_dev->event_data)); + if (ret != EC_RES_INVALID_VERSION) + return ret; - ret = cros_ec_cmd_xfer(ec_dev, msg); - if (ret > 0) { - ec_dev->event_size = ret - 1; - memcpy(&ec_dev->event_data, msg->data, - sizeof(ec_dev->event_data)); + /* Fallback to version 0 for future send attempts */ + cmd_version = 0; } + ret = get_next_event_xfer(ec_dev, msg, cmd_version, + sizeof(struct ec_response_get_next_event)); + return ret; } diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h index 2d4e23c..f3415eb 100644 --- a/include/linux/mfd/cros_ec.h +++ b/include/linux/mfd/cros_ec.h @@ -147,7 +147,7 @@ struct cros_ec_device { bool mkbp_event_supported; struct blocking_notifier_head event_notifier; - struct ec_response_get_next_event event_data; + struct ec_response_get_next_event_v1 event_data; int event_size; u32 host_event_wake_mask; }; diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h index f2edd99..18df466 100644 --- a/include/linux/mfd/cros_ec_commands.h +++ b/include/linux/mfd/cros_ec_commands.h @@ -804,6 +804,8 @@ enum ec_feature_code { EC_FEATURE_MOTION_SENSE_FIFO = 24, /* EC has RTC feature that can be controlled by host commands */ EC_FEATURE_RTC = 27, + /* EC supports CEC commands */ + EC_FEATURE_CEC = 35, }; #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) @@ -2078,6 +2080,12 @@ enum ec_mkbp_event { /* EC sent a sysrq command */ EC_MKBP_EVENT_SYSRQ = 6, + /* Notify the AP that something happened on CEC */ + EC_MKBP_CEC_EVENT = 8, + + /* Send an incoming CEC message to the AP */ + EC_MKBP_EVENT_CEC_MESSAGE = 9, + /* Number of MKBP events */ EC_MKBP_EVENT_COUNT, }; @@ -2093,12 +2101,31 @@ union ec_response_get_next_data { uint32_t sysrq; } __packed; +union ec_response_get_next_data_v1 { + uint8_t key_matrix[16]; + + /* Unaligned */ + uint32_t host_event; + + uint32_t buttons; + uint32_t switches; + uint32_t sysrq; + uint32_t cec_events; + uint8_tcec_message[16]; +} __packed; + struct ec_response_get_next_event { uint8_t event_type; /* Followed by event data if any */ union ec_response_get_next_data data; } __packed; +struct ec_response_get_next_event_v1 { + uint8_t event_type; + /* Followed by event data if any */ + union ec_response_get_next_data_v1 data;
[PATCH 4/5] mfd: cros_ec_dev: Add CEC sub-device registration
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device when the CEC feature bit is present. Signed-off-by: Neil Armstrong --- drivers/mfd/cros_ec_dev.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index eafd06f..57064ec 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -383,6 +383,18 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec) kfree(msg); } +static void cros_ec_cec_register(struct cros_ec_dev *ec) +{ + int ret; + struct mfd_cell cec_cell = { + .name = "cros-ec-cec", + }; + + ret = mfd_add_devices(ec->dev, 0, &cec_cell, 1, NULL, 0, NULL); + if (ret) + dev_err(ec->dev, "failed to add EC CEC\n"); +} + static int ec_device_probe(struct platform_device *pdev) { int retval = -ENOMEM; @@ -422,6 +434,10 @@ static int ec_device_probe(struct platform_device *pdev) if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) cros_ec_sensors_register(ec); + /* check whether this EC handles CEC. */ + if (cros_ec_check_features(ec, EC_FEATURE_CEC)) + cros_ec_cec_register(ec); + /* Take control of the lightbar from the EC. */ lb_manual_suspend_ctrl(ec, 1); -- 2.7.4
[PATCH 1/5] media: cec-notifier: Get notifier by device and connector name
In non device-tree world, we can need to get the notifier by the driver name directly and eventually defer probe if not yet created. This patch adds a variant of the get function by using the device name instead and will not create a notifier if not yet created. But the i915 driver exposes at least 2 HDMI connectors, this patch also adds the possibility to add a connector name tied to the notifier device to form a tuple and associate different CEC controllers for each HDMI connectors. Signed-off-by: Neil Armstrong --- drivers/media/cec/cec-notifier.c | 12 +--- include/media/cec-notifier.h | 30 -- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c index 16dffa0..7038abae1 100644 --- a/drivers/media/cec/cec-notifier.c +++ b/drivers/media/cec/cec-notifier.c @@ -21,6 +21,7 @@ struct cec_notifier { struct list_head head; struct kref kref; struct device *dev; + const char *conn; struct cec_adapter *cec_adap; void (*callback)(struct cec_adapter *adap, u16 pa); @@ -30,13 +31,14 @@ struct cec_notifier { static LIST_HEAD(cec_notifiers); static DEFINE_MUTEX(cec_notifiers_lock); -struct cec_notifier *cec_notifier_get(struct device *dev) +struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn) { struct cec_notifier *n; mutex_lock(&cec_notifiers_lock); list_for_each_entry(n, &cec_notifiers, head) { - if (n->dev == dev) { + if (n->dev == dev && + (!conn || !strcmp(n->conn, conn))) { kref_get(&n->kref); mutex_unlock(&cec_notifiers_lock); return n; @@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev) if (!n) goto unlock; n->dev = dev; + if (conn) + n->conn = kstrdup(conn, GFP_KERNEL); n->phys_addr = CEC_PHYS_ADDR_INVALID; mutex_init(&n->lock); kref_init(&n->kref); @@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev) mutex_unlock(&cec_notifiers_lock); return n; } -EXPORT_SYMBOL_GPL(cec_notifier_get); +EXPORT_SYMBOL_GPL(cec_notifier_get_conn); static void cec_notifier_release(struct kref *kref) { @@ -62,6 +66,8 @@ static void cec_notifier_release(struct kref *kref) container_of(kref, struct cec_notifier, kref); list_del(&n->head); + if (n->conn) + kfree(n->conn); kfree(n); } diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h index cf0add7..73f92c7 100644 --- a/include/media/cec-notifier.h +++ b/include/media/cec-notifier.h @@ -20,6 +20,23 @@ struct cec_notifier; #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) /** + * cec_notifier_get_conn - find or create a new cec_notifier for the given + * device and connector tuple. + * @dev: device that sends the events. + * @conn: the connector name from which the event occurs + * + * If a notifier for device @dev already exists, then increase the refcount + * and return that notifier. + * + * If it doesn't exist, then allocate a new notifier struct and return a + * pointer to that new struct. + * + * Return NULL if the memory could not be allocated. + */ +struct cec_notifier *cec_notifier_get_conn(struct device *dev, + const char *conn); + +/** * cec_notifier_get - find or create a new cec_notifier for the given device. * @dev: device that sends the events. * @@ -31,7 +48,10 @@ struct cec_notifier; * * Return NULL if the memory could not be allocated. */ -struct cec_notifier *cec_notifier_get(struct device *dev); +static inline struct cec_notifier *cec_notifier_get(struct device *dev) +{ + return cec_notifier_get_conn(dev, NULL); +} /** * cec_notifier_put - decrease refcount and delete when the refcount reaches 0. @@ -85,12 +105,18 @@ void cec_register_cec_notifier(struct cec_adapter *adap, struct cec_notifier *notifier); #else -static inline struct cec_notifier *cec_notifier_get(struct device *dev) +static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev, +const char *conn) { /* A non-NULL pointer is expected on success */ return (struct cec_notifier *)0xdeadfeed; } +static inline struct cec_notifier *cec_notifier_get(struct device *dev) +{ + return cec_notifier_get_conn(dev, NULL); +} + static inline void cec_notifier_put(struct cec_notifier *n) { } -- 2.7.4
[PATCH 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi
This patchs adds the cec_notifier feature to the intel_hdmi part of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate between each HDMI ports. The changes will allow the i915 HDMI code to notify EDID and HPD changes to an eventual CEC adapter. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 10 ++ 3 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index dfd9588..2d65d56 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -23,6 +23,7 @@ config DRM_I915 select SYNC_FILE select IOSF_MBI select CRC32 + select CEC_CORE if CEC_NOTIFIER help Choose this option if you have a system that has "Intel Graphics Media Accelerator" or "HD Graphics" integrated graphics, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d436858..b50e51b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -39,6 +39,7 @@ #include #include #include +#include /** * __wait_for - magic wait macro @@ -1001,6 +1002,7 @@ struct intel_hdmi { bool has_audio; bool rgb_quant_range_selectable; struct intel_connector *attached_connector; + struct cec_notifier *notifier; }; struct intel_dp_mst_encoder; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1baef4a..9b94d72 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) connected = true; } + cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid); + return connected; } @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); + if (status != connector_status_connected) + cec_notifier_phys_addr_invalidate(intel_hdmi->notifier); + return status; } @@ -2358,6 +2364,10 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, u32 temp = I915_READ(PEG_BAND_GAP_DATA); I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); } + + intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name); + if (!intel_hdmi->notifier) + DRM_DEBUG_KMS("CEC notifier get failed\n"); } void intel_hdmi_init(struct drm_i915_private *dev_priv, -- 2.7.4
[PATCH 5/5] media: platform: Add Chrome OS EC CEC driver
The Chrome OS Embedded Controller can expose a CEC bus, this patch add the driver for such feature of the Embedded Controller. This driver is part of the cros-ec MFD and will be add as a sub-device when the feature bit is exposed by the EC. The controller will only handle a single logical address and handles all the messages retries and will only expose Success or Error. The controller will be tied to the HDMI CEC notifier by using the platform DMI Data and the i915 device name and connector name. Signed-off-by: Neil Armstrong --- drivers/media/platform/Kconfig | 11 + drivers/media/platform/Makefile | 2 + drivers/media/platform/cros-ec-cec/Makefile | 1 + drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 336 +++ 4 files changed, 350 insertions(+) create mode 100644 drivers/media/platform/cros-ec-cec/Makefile create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index c7a1cf8..e55a8ed2 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS if CEC_PLATFORM_DRIVERS +config VIDEO_CROS_EC_CEC + tristate "Chrome OS EC CEC driver" + depends on MFD_CROS_EC || COMPILE_TEST + select CEC_CORE + select CEC_NOTIFIER + ---help--- + If you say yes here you will get support for the + Chrome OS Embedded Controller's CEC. + The CEC bus is present in the HDMI connector and enables communication + between compatible devices. + config VIDEO_MESON_AO_CEC tristate "Amlogic Meson AO CEC driver" depends on ARCH_MESON || COMPILE_TEST diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 932515d..830696f 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= qcom/camss-8x16/ obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ obj-y += meson/ + +obj-y += cros-ec-cec/ diff --git a/drivers/media/platform/cros-ec-cec/Makefile b/drivers/media/platform/cros-ec-cec/Makefile new file mode 100644 index 000..9ce97f9 --- /dev/null +++ b/drivers/media/platform/cros-ec-cec/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c new file mode 100644 index 000..bbff5d6 --- /dev/null +++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * CEC driver for Chrome OS Embedded Controller + * + * Copyright (c) 2018 BayLibre, SAS + * Author: Neil Armstrong + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This handles the CEC interface to the ChromeOS Embedded Controller, + * but only a single CEC line tied to a single HDMI output is handled now. + */ + +#define DRV_NAME "cros-ec-cec" + +/** + * struct cros_ec_cec - Driver data for EC CEC + * + * @cros_ec: Pointer to EC device + * @notifier: Notifier info for responding to EC events + * @adap: CEC adapter + * @notify: CEC notifier pointer + * @rx_msg: storage for a received message + */ +struct cros_ec_cec { + struct cros_ec_device *cros_ec; + struct notifier_block notifier; + struct cec_adapter *adap; + struct cec_notifier *notify; + struct cec_msg rx_msg; +}; + +static void handle_cec_message(struct cros_ec_cec *cros_ec_cec) +{ + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; + uint8_t *cec_message = cros_ec->event_data.data.cec_message; + unsigned int len = cros_ec->event_size; + + cros_ec_cec->rx_msg.len = len; + memcpy(cros_ec_cec->rx_msg.msg, cec_message, len); + + cec_received_msg(cros_ec_cec->adap, &cros_ec_cec->rx_msg); +} + +static void handle_cec_event(struct cros_ec_cec *cros_ec_cec) +{ + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; + uint32_t events = cros_ec->event_data.data.cec_events; + + if (events & EC_MKBP_CEC_SEND_OK) + cec_transmit_attempt_done(cros_ec_cec->adap, + CEC_TX_STATUS_OK); + + /* FW takes care of all retries, tell core to avoid more retries */ + if (events & EC_MKBP_CEC_SEND_FAILED) + cec_transmit_attempt_done(cros_ec_cec->adap, + CEC_TX_STATUS_MAX_RETRIES | + CEC_TX_STATUS_NACK); +} + +static int cros_ec_cec_event(struct notifier_block *nb, + unsigned long queued_during_suspend, void *_notify) +{ + struct cros_ec_cec *cros_ec_cec; + struct cros_ec_device *cros_ec; + +
[PATCH 0/5] Add ChromeOS EC CEC Support
Hi All, The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support throught it's Embedded Controller, to enable the Linux CEC Core to communicate with it and get the CEC Physical Address from the correct HDMI Connector, the following must be added/changed: - Add the CEC sub-device registration in the ChromeOS EC MFD Driver - Add the CEC related commands and events definitions into the EC MFD driver - Add a way to get a CEC notifier with it's (optional) connector name - Add the CEC notifier to the i915 HDMI driver - Add the proper ChromeOS EC CEC Driver The CEC notifier with the connector name is the tricky point, since even on Device-Tree platforms, there is no way to distinguish between multiple HDMI connectors from the same DRM driver. The solution I implemented is pretty simple and only adds an optional connector name to eventually distinguish an HDMI connector notifier from another if they share the same device. Feel free to comment this patchset ! Changes since RFC: - Moved CEC sub-device registration after CEC commands and events definitions patch - Removed get_notifier_get_byname - Added CEC_CORE select into i915 Kconfig - Removed CEC driver fallback if notifier is not configured on HW, added explicit warn - Fixed CEC core return type on error - Moved to cros-ec-cec media platform directory - Use bus_find_device() to find the pci i915 device instead of get_notifier_get_byname() - Fix Logical Address setup - Added comment about HW support - Removed memset of msg structures Neil Armstrong (5): media: cec-notifier: Get notifier by device and connector name drm/i915: hdmi: add CEC notifier to intel_hdmi mfd: cros-ec: Introduce CEC commands and events definitions. mfd: cros_ec_dev: Add CEC sub-device registration media: platform: Add Chrome OS EC CEC driver drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_hdmi.c| 10 + drivers/media/cec/cec-notifier.c | 12 +- drivers/media/platform/Kconfig | 11 + drivers/media/platform/Makefile | 2 + drivers/media/platform/cros-ec-cec/Makefile | 1 + drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 336 +++ drivers/mfd/cros_ec_dev.c| 16 ++ drivers/platform/chrome/cros_ec_proto.c | 42 ++- include/linux/mfd/cros_ec.h | 2 +- include/linux/mfd/cros_ec_commands.h | 80 ++ include/media/cec-notifier.h | 30 +- 13 files changed, 530 insertions(+), 15 deletions(-) create mode 100644 drivers/media/platform/cros-ec-cec/Makefile create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c -- 2.7.4
Re: Grant
I Mikhail Fridman. has selected you specially as one of my beneficiaries for my Charitable Donation, Just as I have declared on May 23, 2016 to give my fortune as charity. Check the link below for confirmation: http://www.ibtimes.co.uk/russias-second-wealthiest-man-mikhail-fridman-plans-leaving-14-2bn-fortune-charity-1561604 Reply as soon as possible with further directives. Best Regards, Mikhail Fridman.
Re: [PATCH 1/5] media: cec-notifier: Get notifier by device and connector name
Hi Neil, Two small comments below: On 05/15/18 14:46, Neil Armstrong wrote: > In non device-tree world, we can need to get the notifier by the driver > name directly and eventually defer probe if not yet created. > > This patch adds a variant of the get function by using the device name > instead and will not create a notifier if not yet created. > > But the i915 driver exposes at least 2 HDMI connectors, this patch also > adds the possibility to add a connector name tied to the notifier device > to form a tuple and associate different CEC controllers for each HDMI > connectors. > > Signed-off-by: Neil Armstrong > --- > drivers/media/cec/cec-notifier.c | 12 +--- > include/media/cec-notifier.h | 30 -- > 2 files changed, 37 insertions(+), 5 deletions(-) > > diff --git a/drivers/media/cec/cec-notifier.c > b/drivers/media/cec/cec-notifier.c > index 16dffa0..7038abae1 100644 > --- a/drivers/media/cec/cec-notifier.c > +++ b/drivers/media/cec/cec-notifier.c > @@ -21,6 +21,7 @@ struct cec_notifier { > struct list_head head; > struct kref kref; > struct device *dev; > + const char *conn; > struct cec_adapter *cec_adap; > void (*callback)(struct cec_adapter *adap, u16 pa); > > @@ -30,13 +31,14 @@ struct cec_notifier { > static LIST_HEAD(cec_notifiers); > static DEFINE_MUTEX(cec_notifiers_lock); > > -struct cec_notifier *cec_notifier_get(struct device *dev) > +struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char > *conn) > { > struct cec_notifier *n; > > mutex_lock(&cec_notifiers_lock); > list_for_each_entry(n, &cec_notifiers, head) { > - if (n->dev == dev) { > + if (n->dev == dev && > + (!conn || !strcmp(n->conn, conn))) { > kref_get(&n->kref); > mutex_unlock(&cec_notifiers_lock); > return n; > @@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev) > if (!n) > goto unlock; > n->dev = dev; > + if (conn) > + n->conn = kstrdup(conn, GFP_KERNEL); > n->phys_addr = CEC_PHYS_ADDR_INVALID; > mutex_init(&n->lock); > kref_init(&n->kref); > @@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev) > mutex_unlock(&cec_notifiers_lock); > return n; > } > -EXPORT_SYMBOL_GPL(cec_notifier_get); > +EXPORT_SYMBOL_GPL(cec_notifier_get_conn); > > static void cec_notifier_release(struct kref *kref) > { > @@ -62,6 +66,8 @@ static void cec_notifier_release(struct kref *kref) > container_of(kref, struct cec_notifier, kref); > > list_del(&n->head); > + if (n->conn) No need for this if, kfree already tests the pointer. > + kfree(n->conn); > kfree(n); > } > > diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h > index cf0add7..73f92c7 100644 > --- a/include/media/cec-notifier.h > +++ b/include/media/cec-notifier.h > @@ -20,6 +20,23 @@ struct cec_notifier; > #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) > > /** > + * cec_notifier_get_conn - find or create a new cec_notifier for the given > + * device and connector tuple. > + * @dev: device that sends the events. > + * @conn: the connector name from which the event occurs > + * > + * If a notifier for device @dev already exists, then increase the refcount > + * and return that notifier. > + * > + * If it doesn't exist, then allocate a new notifier struct and return a > + * pointer to that new struct. > + * > + * Return NULL if the memory could not be allocated. > + */ > +struct cec_notifier *cec_notifier_get_conn(struct device *dev, > +const char *conn); > + > +/** > * cec_notifier_get - find or create a new cec_notifier for the given device. > * @dev: device that sends the events. > * > @@ -31,7 +48,10 @@ struct cec_notifier; > * > * Return NULL if the memory could not be allocated. > */ > -struct cec_notifier *cec_notifier_get(struct device *dev); > +static inline struct cec_notifier *cec_notifier_get(struct device *dev) > +{ > + return cec_notifier_get_conn(dev, NULL); > +} > > /** > * cec_notifier_put - decrease refcount and delete when the refcount reaches > 0. > @@ -85,12 +105,18 @@ void cec_register_cec_notifier(struct cec_adapter *adap, > struct cec_notifier *notifier); > > #else > -static inline struct cec_notifier *cec_notifier_get(struct device *dev) > +static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev, > + const char *conn) > { > /* A non-NULL pointer is expected on success */ > return (struct cec_notifier *)0xdeadfeed; > } > > +static inline struct cec_notifier *cec_notifier_get(struct device *dev) > +{ > + return cec_notifier_get_conn(dev, NULL); >
Re: [PATCH] usbtv: Fix refcounting mixup
On Tue, May 15, 2018 at 01:51:37PM +0200, Oliver Neukum wrote: > The premature free in the error path is blocked by V4L > refcounting, not USB refcounting. Thanks to > Ben Hutchings for review. > > Signed-off-by: Oliver Neukum > Fixes: 50e704453553 ("media: usbtv: prevent double free in error case") Please add: Cc: stable to this patch as well so I pick up the fix in the stable trees. And a "Reported-by:" line would be nice as well to give credit to Ben :) thanks, greg k-h
Re: [PATCH 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi
On 05/15/18 14:46, Neil Armstrong wrote: > This patchs adds the cec_notifier feature to the intel_hdmi part > of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate > between each HDMI ports. > The changes will allow the i915 HDMI code to notify EDID and HPD changes > to an eventual CEC adapter. You haven't figured yet out where to place the cec_notifier_put() call? Or did you forget? Regards, Hans > > Signed-off-by: Neil Armstrong > --- > drivers/gpu/drm/i915/Kconfig | 1 + > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > drivers/gpu/drm/i915/intel_hdmi.c | 10 ++ > 3 files changed, 13 insertions(+) > > diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig > index dfd9588..2d65d56 100644 > --- a/drivers/gpu/drm/i915/Kconfig > +++ b/drivers/gpu/drm/i915/Kconfig > @@ -23,6 +23,7 @@ config DRM_I915 > select SYNC_FILE > select IOSF_MBI > select CRC32 > + select CEC_CORE if CEC_NOTIFIER > help > Choose this option if you have a system that has "Intel Graphics > Media Accelerator" or "HD Graphics" integrated graphics, > diff --git a/drivers/gpu/drm/i915/intel_drv.h > b/drivers/gpu/drm/i915/intel_drv.h > index d436858..b50e51b 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -39,6 +39,7 @@ > #include > #include > #include > +#include > > /** > * __wait_for - magic wait macro > @@ -1001,6 +1002,7 @@ struct intel_hdmi { > bool has_audio; > bool rgb_quant_range_selectable; > struct intel_connector *attached_connector; > + struct cec_notifier *notifier; > }; > > struct intel_dp_mst_encoder; > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c > b/drivers/gpu/drm/i915/intel_hdmi.c > index 1baef4a..9b94d72 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) > connected = true; > } > > + cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid); > + > return connected; > } > > @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool > force) > { > enum drm_connector_status status; > struct drm_i915_private *dev_priv = to_i915(connector->dev); > + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > connector->base.id, connector->name); > @@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool > force) > > intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > > + if (status != connector_status_connected) > + cec_notifier_phys_addr_invalidate(intel_hdmi->notifier); > + > return status; > } > > @@ -2358,6 +2364,10 @@ void intel_hdmi_init_connector(struct > intel_digital_port *intel_dig_port, > u32 temp = I915_READ(PEG_BAND_GAP_DATA); > I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); > } > + > + intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name); > + if (!intel_hdmi->notifier) > + DRM_DEBUG_KMS("CEC notifier get failed\n"); > } > > void intel_hdmi_init(struct drm_i915_private *dev_priv, >
[PATCH] media: dvb_ca_en50221: prevent using slot_info for Spectre attacs
slot can be controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability, as warned by smatch: drivers/media/dvb-core/dvb_ca_en50221.c:1479 dvb_ca_en50221_io_write() warn: potential spectre issue 'ca->slot_info' (local cap) Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 97365a863519..1310526b0d49 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1476,6 +1477,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, if (slot >= ca->slot_count) return -EINVAL; + slot = array_index_nospec(slot, ca->slot_count); sl = &ca->slot_info[slot]; /* check if the slot is actually running */ -- 2.17.0
Re: [PATCH 5/5] media: platform: Add Chrome OS EC CEC driver
Some small comments below: On 05/15/18 14:47, Neil Armstrong wrote: > The Chrome OS Embedded Controller can expose a CEC bus, this patch add the > driver for such feature of the Embedded Controller. > > This driver is part of the cros-ec MFD and will be add as a sub-device when > the feature bit is exposed by the EC. > > The controller will only handle a single logical address and handles > all the messages retries and will only expose Success or Error. > > The controller will be tied to the HDMI CEC notifier by using the platform > DMI Data and the i915 device name and connector name. > > Signed-off-by: Neil Armstrong > --- > drivers/media/platform/Kconfig | 11 + > drivers/media/platform/Makefile | 2 + > drivers/media/platform/cros-ec-cec/Makefile | 1 + > drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 336 > +++ > 4 files changed, 350 insertions(+) > create mode 100644 drivers/media/platform/cros-ec-cec/Makefile > create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c > > diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig > index c7a1cf8..e55a8ed2 100644 > --- a/drivers/media/platform/Kconfig > +++ b/drivers/media/platform/Kconfig > @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS > > if CEC_PLATFORM_DRIVERS > > +config VIDEO_CROS_EC_CEC > + tristate "Chrome OS EC CEC driver" > + depends on MFD_CROS_EC || COMPILE_TEST > + select CEC_CORE > + select CEC_NOTIFIER > + ---help--- > + If you say yes here you will get support for the > + Chrome OS Embedded Controller's CEC. > + The CEC bus is present in the HDMI connector and enables communication > + between compatible devices. > + > config VIDEO_MESON_AO_CEC > tristate "Amlogic Meson AO CEC driver" > depends on ARCH_MESON || COMPILE_TEST > diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile > index 932515d..830696f 100644 > --- a/drivers/media/platform/Makefile > +++ b/drivers/media/platform/Makefile > @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += > qcom/camss-8x16/ > obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ > > obj-y+= meson/ > + > +obj-y+= cros-ec-cec/ > diff --git a/drivers/media/platform/cros-ec-cec/Makefile > b/drivers/media/platform/cros-ec-cec/Makefile > new file mode 100644 > index 000..9ce97f9 > --- /dev/null > +++ b/drivers/media/platform/cros-ec-cec/Makefile > @@ -0,0 +1 @@ > +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o > diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c > b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c > new file mode 100644 > index 000..bbff5d6 > --- /dev/null > +++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c > @@ -0,0 +1,336 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * CEC driver for Chrome OS Embedded Controller > + * > + * Copyright (c) 2018 BayLibre, SAS > + * Author: Neil Armstrong > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* > + * This handles the CEC interface to the ChromeOS Embedded Controller, > + * but only a single CEC line tied to a single HDMI output is handled now. > + */ > + > +#define DRV_NAME "cros-ec-cec" > + > +/** > + * struct cros_ec_cec - Driver data for EC CEC > + * > + * @cros_ec: Pointer to EC device > + * @notifier: Notifier info for responding to EC events > + * @adap: CEC adapter > + * @notify: CEC notifier pointer > + * @rx_msg: storage for a received message > + */ > +struct cros_ec_cec { > + struct cros_ec_device *cros_ec; > + struct notifier_block notifier; > + struct cec_adapter *adap; > + struct cec_notifier *notify; > + struct cec_msg rx_msg; > +}; > + > +static void handle_cec_message(struct cros_ec_cec *cros_ec_cec) > +{ > + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; > + uint8_t *cec_message = cros_ec->event_data.data.cec_message; > + unsigned int len = cros_ec->event_size; > + > + cros_ec_cec->rx_msg.len = len; > + memcpy(cros_ec_cec->rx_msg.msg, cec_message, len); > + > + cec_received_msg(cros_ec_cec->adap, &cros_ec_cec->rx_msg); > +} > + > +static void handle_cec_event(struct cros_ec_cec *cros_ec_cec) > +{ > + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; > + uint32_t events = cros_ec->event_data.data.cec_events; > + > + if (events & EC_MKBP_CEC_SEND_OK) > + cec_transmit_attempt_done(cros_ec_cec->adap, > + CEC_TX_STATUS_OK); > + > + /* FW takes care of all retries, tell core to avoid more retries */ > + if (events & EC_MKBP_CEC_SEND_FAILED) > + cec_transmit_attempt_done(cros_ec_cec->adap, > + CEC
[PATCH] [Patch v2] usbtv: Fix refcounting mixup
The premature free in the error path is blocked by V4L refcounting, not USB refcounting. Thanks to Ben Hutchings for review. [v2] corrected attributions Signed-off-by: Oliver Neukum Fixes: 50e704453553 ("media: usbtv: prevent double free in error case") CC: sta...@vger.kernel.org Reported-by: Ben Hutchings --- drivers/media/usb/usbtv/usbtv-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c index 5095c380b2c1..4a03c4d66314 100644 --- a/drivers/media/usb/usbtv/usbtv-core.c +++ b/drivers/media/usb/usbtv/usbtv-core.c @@ -113,7 +113,8 @@ static int usbtv_probe(struct usb_interface *intf, usbtv_audio_fail: /* we must not free at this point */ - usb_get_dev(usbtv->udev); + v4l2_device_get(&usbtv->v4l2_dev); + /* this will undo the v4l2_device_get() */ usbtv_video_free(usbtv); usbtv_video_fail: -- 2.13.6
Re: [PATCH v2 11/12] media: ov5640: Add 60 fps support
Hi Maxime, I've taken the whole serie and made some tests on STM32 platform using DVP parallel interface. Now JPEG is OK and I've not seen any regressions appart on framerate control linked to this current patchset. Here are issues observed around framerate control: 1) Framerate enumeration is buggy and all resolutions are claimed supporting 15/30/60: v4l2-ctl --list-formats-ext ioctl: VIDIOC_ENUM_FMT Index : 0 Type: Video Capture Pixel Format: 'JPEG' (compressed) Name: JFIF JPEG Size: Discrete 176x144 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 320x240 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 640x480 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 720x480 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 720x576 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 1024x768 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 1280x720 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 1920x1080 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 2592x1944 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) 2) Frame interval setting is returning incorrect value (*1000): v4l2-ctl --set-parm=15 < Frame rate set to 15000.000 fps 3) After having fixed 1) and 2), 720x480 60fps is still supported: Size: Discrete 640x480 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Size: Discrete 720x480 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.017s (60.000 fps) Some fixes are proposed below: On 04/16/2018 02:37 PM, Maxime Ripard wrote: > Now that we have everything in place to compute the clock rate at runtime, > we can enable the 60fps framerate for the mode we tested it with. > > Signed-off-by: Maxime Ripard > --- > drivers/media/i2c/ov5640.c | 33 + > 1 file changed, 25 insertions(+), 8 deletions(-) > > diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c > index 690ed0238763..c01bbc5f9f34 100644 > --- a/drivers/media/i2c/ov5640.c > +++ b/drivers/media/i2c/ov5640.c > @@ -112,6 +112,7 @@ enum ov5640_mode_id { > enum ov5640_frame_rate { > OV5640_15_FPS = 0, > OV5640_30_FPS, > + OV5640_60_FPS, > OV5640_NUM_FRAMERATES, > }; > > @@ -140,6 +141,7 @@ MODULE_PARM_DESC(virtual_channel, > static const int ov5640_framerates[] = { > [OV5640_15_FPS] = 15, > [OV5640_30_FPS] = 30, > + [OV5640_60_FPS] = 60, > }; > > /* regulator supplies */ > @@ -1398,12 +1400,19 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum > ov5640_frame_rate fr, > /* try to find another mode */ > continue; > > + /* Only 640x480 can operate at 60fps (for now) */ > + if (fr == OV5640_60_FPS && > + width != 640 && height != 480) Should be + !(width == 640 && height == 480)) otherwise 720x480 is also supported (bug 3)) > + /* try to find another mode */ > + continue; > + > break; > } > } > > + /* VGA is the
Re: [PATCH 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi
Hi, On 15/05/2018 14:56, Hans Verkuil wrote: > On 05/15/18 14:46, Neil Armstrong wrote: >> This patchs adds the cec_notifier feature to the intel_hdmi part >> of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate >> between each HDMI ports. >> The changes will allow the i915 HDMI code to notify EDID and HPD changes >> to an eventual CEC adapter. > > You haven't figured yet out where to place the cec_notifier_put() call? > Or did you forget? I just figured it out, I was busy on the CEC driver and notifier, will re-spin a v2 with this and the other small fixes you requested. Thanks, Neil > > Regards, > > Hans > >> >> Signed-off-by: Neil Armstrong >> --- >> drivers/gpu/drm/i915/Kconfig | 1 + >> drivers/gpu/drm/i915/intel_drv.h | 2 ++ >> drivers/gpu/drm/i915/intel_hdmi.c | 10 ++ >> 3 files changed, 13 insertions(+) >> >> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig >> index dfd9588..2d65d56 100644 >> --- a/drivers/gpu/drm/i915/Kconfig >> +++ b/drivers/gpu/drm/i915/Kconfig >> @@ -23,6 +23,7 @@ config DRM_I915 >> select SYNC_FILE >> select IOSF_MBI >> select CRC32 >> +select CEC_CORE if CEC_NOTIFIER >> help >>Choose this option if you have a system that has "Intel Graphics >>Media Accelerator" or "HD Graphics" integrated graphics, >> diff --git a/drivers/gpu/drm/i915/intel_drv.h >> b/drivers/gpu/drm/i915/intel_drv.h >> index d436858..b50e51b 100644 >> --- a/drivers/gpu/drm/i915/intel_drv.h >> +++ b/drivers/gpu/drm/i915/intel_drv.h >> @@ -39,6 +39,7 @@ >> #include >> #include >> #include >> +#include >> >> /** >> * __wait_for - magic wait macro >> @@ -1001,6 +1002,7 @@ struct intel_hdmi { >> bool has_audio; >> bool rgb_quant_range_selectable; >> struct intel_connector *attached_connector; >> +struct cec_notifier *notifier; >> }; >> >> struct intel_dp_mst_encoder; >> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c >> b/drivers/gpu/drm/i915/intel_hdmi.c >> index 1baef4a..9b94d72 100644 >> --- a/drivers/gpu/drm/i915/intel_hdmi.c >> +++ b/drivers/gpu/drm/i915/intel_hdmi.c >> @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) >> connected = true; >> } >> >> +cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid); >> + >> return connected; >> } >> >> @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, >> bool force) >> { >> enum drm_connector_status status; >> struct drm_i915_private *dev_priv = to_i915(connector->dev); >> +struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); >> >> DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", >>connector->base.id, connector->name); >> @@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, >> bool force) >> >> intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); >> >> +if (status != connector_status_connected) >> +cec_notifier_phys_addr_invalidate(intel_hdmi->notifier); >> + >> return status; >> } >> >> @@ -2358,6 +2364,10 @@ void intel_hdmi_init_connector(struct >> intel_digital_port *intel_dig_port, >> u32 temp = I915_READ(PEG_BAND_GAP_DATA); >> I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); >> } >> + >> +intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name); >> +if (!intel_hdmi->notifier) >> +DRM_DEBUG_KMS("CEC notifier get failed\n"); >> } >> >> void intel_hdmi_init(struct drm_i915_private *dev_priv, >> >
Re: [PATCH 01/11] media: tm6000: fix potential Spectre variant 1
On Tue, May 15, 2018 at 08:59:53AM -0300, Mauro Carvalho Chehab wrote: > Em Mon, 14 May 2018 22:31:37 -0500 > "Gustavo A. R. Silva" escreveu: > > > Hi Mauro, > > > > On 04/26/2018 06:42 PM, Mauro Carvalho Chehab wrote: > > > > >> > > >> I noticed you changed the status of this series from rejected to new. > > > > > > Yes. > > > > > >> Also, there are other similar issues in media/pci/ > > > > > > Well, the issues will be there everywhere on all media drivers. > > > > > > I marked your patches because I need to study it carefully, after > > > Peter's explanations. My plan is to do it next week. Still not > > > sure if the approach you took is the best one or not. > > > > > > As I said, one possibility is to change the way v4l2-core handles > > > VIDIOC_ENUM_foo ioctls, but that would be make harder to -stable > > > backports. > > > > > > I need a weekend to sleep on it. > > > > > > > I'm curious about how you finally resolved to handle these issues. > > > > I noticed Smatch is no longer reporting them. > > There was no direct fix for it, but maybe this patch has something > to do with the smatch error report cleanup: > > commit 3ad3b7a2ebaefae37a7eafed0779324987ca5e56 > Author: Sami Tolvanen > Date: Tue May 8 13:56:12 2018 -0400 > > media: v4l2-ioctl: replace IOCTL_INFO_STD with stub functions > > This change removes IOCTL_INFO_STD and adds stub functions where > needed using the DEFINE_V4L_STUB_FUNC macro. This fixes indirect call > mismatches with Control-Flow Integrity, caused by calling standard > ioctls using a function pointer that doesn't match the function type. > > Signed-off-by: Sami Tolvanen > Signed-off-by: Hans Verkuil > Signed-off-by: Mauro Carvalho Chehab > Possibly... There was an ancient bug in Smatch's function pointer handling. I just pushed a fix for it now so the warning is there on linux-next. regards, dan carpenter
Re: [PATCH] [Patch v2] usbtv: Fix refcounting mixup
On 05/15/18 15:07, Oliver Neukum wrote: > The premature free in the error path is blocked by V4L > refcounting, not USB refcounting. Thanks to > Ben Hutchings for review. > > [v2] corrected attributions > > Signed-off-by: Oliver Neukum > Fixes: 50e704453553 ("media: usbtv: prevent double free in error case") > CC: sta...@vger.kernel.org > Reported-by: Ben Hutchings > --- > drivers/media/usb/usbtv/usbtv-core.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/usb/usbtv/usbtv-core.c > b/drivers/media/usb/usbtv/usbtv-core.c > index 5095c380b2c1..4a03c4d66314 100644 > --- a/drivers/media/usb/usbtv/usbtv-core.c > +++ b/drivers/media/usb/usbtv/usbtv-core.c > @@ -113,7 +113,8 @@ static int usbtv_probe(struct usb_interface *intf, > > usbtv_audio_fail: > /* we must not free at this point */ > - usb_get_dev(usbtv->udev); > + v4l2_device_get(&usbtv->v4l2_dev); This is very confusing. I think it is much better to move the v4l2_device_register() call from usbtv_video_init to this probe function. The extra v4l2_device_get in the probe() can just be dropped and usbtv_video_free() no longer needs to call v4l2_device_put(). The only place you need a v4l2_device_put() is in the disconnect() function at the end. Regards, Hans > + /* this will undo the v4l2_device_get() */ > usbtv_video_free(usbtv); > > usbtv_video_fail: >
[GIT PULL FOR v4.18] Various fixes, move zoran to staging
Besides the various fixes the main change is that the zoran driver is moved to staging with the intention to remove it next year. Regards, Hans The following changes since commit 2a5f2705c97625aa1a4e1dd4d584eaa05392e060: media: lgdt330x.h: fix compiler warning (2018-05-11 11:40:09 -0400) are available in the git repository at: git://linuxtv.org/hverkuil/media_tree.git for-v4.18d for you to fetch changes up to ca575b76cf4a0b2ae851d398e1725f43fc81e7c8: adv7511: fix clearing of the CEC receive buffer (2018-05-15 16:28:35 +0200) Ezequiel Garcia (1): usbtv: Implement wait_prepare and wait_finish Fabien Dessenne (2): media: bdisp: don't use GFP_DMA media: st-hva: don't use GFP_DMA Hans Verkuil (10): zoran: move to staging in preparation for removal go7007: fix two sparse warnings zoran: fix compiler warning s5p-mfc: fix two sparse warnings hdpvr: fix compiler warning imx: fix compiler warning renesas-ceu: fix compiler warning soc_camera: fix compiler warning cec: improve cec status documentation adv7511: fix clearing of the CEC receive buffer Laurent Pinchart (1): media: i2c: adv748x: Fix pixel rate values Luca Ceresoli (5): media: docs: selection: fix typos media: docs: clarify relationship between crop and selection APIs media: docs: selection: rename files to something meaningful media: docs: selection: improve formatting media: docs: selection: fix misleading sentence about the CROP API Documentation/media/kapi/cec-core.rst | 5 - Documentation/media/uapi/cec/cec-ioc-receive.rst | 24 +++- Documentation/media/uapi/v4l/common.rst | 2 +- Documentation/media/uapi/v4l/crop.rst | 22 +++--- Documentation/media/uapi/v4l/selection-api-005.rst | 34 -- Documentation/media/uapi/v4l/{selection-api-004.rst => selection-api-configuration.rst} | 2 +- Documentation/media/uapi/v4l/{selection-api-006.rst => selection-api-examples.rst} | 0 Documentation/media/uapi/v4l/{selection-api-002.rst => selection-api-intro.rst} | 0 Documentation/media/uapi/v4l/{selection-api-003.rst => selection-api-targets.rst} | 0 Documentation/media/uapi/v4l/selection-api-vs-crop-api.rst | 39 +++ Documentation/media/uapi/v4l/selection-api.rst | 14 +++--- Documentation/media/uapi/v4l/selection.svg | 4 ++-- MAINTAINERS | 2 +- drivers/media/i2c/adv748x/adv748x-afe.c | 12 ++-- drivers/media/i2c/adv748x/adv748x-hdmi.c | 8 +--- drivers/media/i2c/adv7511.c | 18 +- drivers/media/pci/Kconfig | 1 - drivers/media/pci/Makefile | 1 - drivers/media/platform/renesas-ceu.c | 2 +- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 4 ++-- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 4 ++-- drivers/media/platform/soc_camera/soc_camera_platform.c | 3 ++- drivers/media/platform/sti/bdisp/bdisp-hw.c | 2 +- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 4 drivers/media/platform/sti/hva/hva-mem.c | 2 +- drivers/media/platform/sti/hva/hva-v4l2.c | 4 drivers/media/usb/go7007/go7007-fw.c | 3 +++ drivers/media/usb/go7007/go7007-v4l2.c | 2 +- drivers/media/usb/hdpvr/hdpvr-video.c | 2 +- drivers/media/usb/usbtv/usbtv-video.c | 2 ++ drivers/staging/media/Kconfig | 2 ++ drivers/staging/media/Makefile | 1 + drivers/staging/media/imx/imx-media-capture.c
[PATCH v2 4/5] mfd: cros_ec_dev: Add CEC sub-device registration
The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device when the CEC feature bit is present. Signed-off-by: Neil Armstrong --- drivers/mfd/cros_ec_dev.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index eafd06f..57064ec 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -383,6 +383,18 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec) kfree(msg); } +static void cros_ec_cec_register(struct cros_ec_dev *ec) +{ + int ret; + struct mfd_cell cec_cell = { + .name = "cros-ec-cec", + }; + + ret = mfd_add_devices(ec->dev, 0, &cec_cell, 1, NULL, 0, NULL); + if (ret) + dev_err(ec->dev, "failed to add EC CEC\n"); +} + static int ec_device_probe(struct platform_device *pdev) { int retval = -ENOMEM; @@ -422,6 +434,10 @@ static int ec_device_probe(struct platform_device *pdev) if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) cros_ec_sensors_register(ec); + /* check whether this EC handles CEC. */ + if (cros_ec_check_features(ec, EC_FEATURE_CEC)) + cros_ec_cec_register(ec); + /* Take control of the lightbar from the EC. */ lb_manual_suspend_ctrl(ec, 1); -- 2.7.4
[PATCH v2 5/5] media: platform: Add Chrome OS EC CEC driver
The Chrome OS Embedded Controller can expose a CEC bus, this patch add the driver for such feature of the Embedded Controller. This driver is part of the cros-ec MFD and will be add as a sub-device when the feature bit is exposed by the EC. The controller will only handle a single logical address and handles all the messages retries and will only expose Success or Error. The controller will be tied to the HDMI CEC notifier by using the platform DMI Data and the i915 device name and connector name. Signed-off-by: Neil Armstrong --- drivers/media/platform/Kconfig | 11 + drivers/media/platform/Makefile | 2 + drivers/media/platform/cros-ec-cec/Makefile | 1 + drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 335 +++ 4 files changed, 349 insertions(+) create mode 100644 drivers/media/platform/cros-ec-cec/Makefile create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index c7a1cf8..e55a8ed2 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS if CEC_PLATFORM_DRIVERS +config VIDEO_CROS_EC_CEC + tristate "Chrome OS EC CEC driver" + depends on MFD_CROS_EC || COMPILE_TEST + select CEC_CORE + select CEC_NOTIFIER + ---help--- + If you say yes here you will get support for the + Chrome OS Embedded Controller's CEC. + The CEC bus is present in the HDMI connector and enables communication + between compatible devices. + config VIDEO_MESON_AO_CEC tristate "Amlogic Meson AO CEC driver" depends on ARCH_MESON || COMPILE_TEST diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 932515d..830696f 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= qcom/camss-8x16/ obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ obj-y += meson/ + +obj-y += cros-ec-cec/ diff --git a/drivers/media/platform/cros-ec-cec/Makefile b/drivers/media/platform/cros-ec-cec/Makefile new file mode 100644 index 000..9ce97f9 --- /dev/null +++ b/drivers/media/platform/cros-ec-cec/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c new file mode 100644 index 000..aed3368 --- /dev/null +++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * CEC driver for Chrome OS Embedded Controller + * + * Copyright (c) 2018 BayLibre, SAS + * Author: Neil Armstrong + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "cros-ec-cec" + +/** + * struct cros_ec_cec - Driver data for EC CEC + * + * @cros_ec: Pointer to EC device + * @notifier: Notifier info for responding to EC events + * @adap: CEC adapter + * @notify: CEC notifier pointer + * @rx_msg: storage for a received message + */ +struct cros_ec_cec { + struct cros_ec_device *cros_ec; + struct notifier_block notifier; + struct cec_adapter *adap; + struct cec_notifier *notify; + struct cec_msg rx_msg; +}; + +static void handle_cec_message(struct cros_ec_cec *cros_ec_cec) +{ + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; + uint8_t *cec_message = cros_ec->event_data.data.cec_message; + unsigned int len = cros_ec->event_size; + + cros_ec_cec->rx_msg.len = len; + memcpy(cros_ec_cec->rx_msg.msg, cec_message, len); + + cec_received_msg(cros_ec_cec->adap, &cros_ec_cec->rx_msg); +} + +static void handle_cec_event(struct cros_ec_cec *cros_ec_cec) +{ + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; + uint32_t events = cros_ec->event_data.data.cec_events; + + if (events & EC_MKBP_CEC_SEND_OK) + cec_transmit_attempt_done(cros_ec_cec->adap, + CEC_TX_STATUS_OK); + + /* FW takes care of all retries, tell core to avoid more retries */ + if (events & EC_MKBP_CEC_SEND_FAILED) + cec_transmit_attempt_done(cros_ec_cec->adap, + CEC_TX_STATUS_MAX_RETRIES | + CEC_TX_STATUS_NACK); +} + +static int cros_ec_cec_event(struct notifier_block *nb, +unsigned long queued_during_suspend, +void *_notify) +{ + struct cros_ec_cec *cros_ec_cec; + struct cros_ec_device *cros_ec; + + cros_ec_cec = container_of(nb, struct cros_ec_cec, notifier); + cros_ec = cros_ec_cec->cros_ec; + +
[PATCH v2 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.
The EC can expose a CEC bus, this patch adds the CEC related definitions needed by the cros-ec-cec driver. Having a 16 byte mkbp event size makes it possible to send CEC messages from the EC to the AP directly inside the mkbp event instead of first doing a notification and then a read. Signed-off-by: Stefan Adolfsson Signed-off-by: Neil Armstrong --- drivers/platform/chrome/cros_ec_proto.c | 42 + include/linux/mfd/cros_ec.h | 2 +- include/linux/mfd/cros_ec_commands.h| 80 + 3 files changed, 114 insertions(+), 10 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index e7bbdf9..ba47f79 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -504,29 +504,53 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, } EXPORT_SYMBOL(cros_ec_cmd_xfer_status); +static int get_next_event_xfer(struct cros_ec_device *ec_dev, + struct cros_ec_command *msg, + int version, uint32_t size) +{ + int ret; + + msg->version = version; + msg->command = EC_CMD_GET_NEXT_EVENT; + msg->insize = size; + msg->outsize = 0; + + ret = cros_ec_cmd_xfer(ec_dev, msg); + if (ret > 0) { + ec_dev->event_size = ret - 1; + memcpy(&ec_dev->event_data, msg->data, size); + } + + return ret; +} + static int get_next_event(struct cros_ec_device *ec_dev) { u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)]; struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; + static int cmd_version = 1; int ret; + BUILD_BUG_ON(sizeof(union ec_response_get_next_data_v1) != 16); + if (ec_dev->suspended) { dev_dbg(ec_dev->dev, "Device suspended.\n"); return -EHOSTDOWN; } - msg->version = 0; - msg->command = EC_CMD_GET_NEXT_EVENT; - msg->insize = sizeof(ec_dev->event_data); - msg->outsize = 0; + if (cmd_version == 1) { + ret = get_next_event_xfer(ec_dev, msg, cmd_version, + sizeof(ec_dev->event_data)); + if (ret != EC_RES_INVALID_VERSION) + return ret; - ret = cros_ec_cmd_xfer(ec_dev, msg); - if (ret > 0) { - ec_dev->event_size = ret - 1; - memcpy(&ec_dev->event_data, msg->data, - sizeof(ec_dev->event_data)); + /* Fallback to version 0 for future send attempts */ + cmd_version = 0; } + ret = get_next_event_xfer(ec_dev, msg, cmd_version, + sizeof(struct ec_response_get_next_event)); + return ret; } diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h index 2d4e23c..f3415eb 100644 --- a/include/linux/mfd/cros_ec.h +++ b/include/linux/mfd/cros_ec.h @@ -147,7 +147,7 @@ struct cros_ec_device { bool mkbp_event_supported; struct blocking_notifier_head event_notifier; - struct ec_response_get_next_event event_data; + struct ec_response_get_next_event_v1 event_data; int event_size; u32 host_event_wake_mask; }; diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h index f2edd99..18df466 100644 --- a/include/linux/mfd/cros_ec_commands.h +++ b/include/linux/mfd/cros_ec_commands.h @@ -804,6 +804,8 @@ enum ec_feature_code { EC_FEATURE_MOTION_SENSE_FIFO = 24, /* EC has RTC feature that can be controlled by host commands */ EC_FEATURE_RTC = 27, + /* EC supports CEC commands */ + EC_FEATURE_CEC = 35, }; #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) @@ -2078,6 +2080,12 @@ enum ec_mkbp_event { /* EC sent a sysrq command */ EC_MKBP_EVENT_SYSRQ = 6, + /* Notify the AP that something happened on CEC */ + EC_MKBP_CEC_EVENT = 8, + + /* Send an incoming CEC message to the AP */ + EC_MKBP_EVENT_CEC_MESSAGE = 9, + /* Number of MKBP events */ EC_MKBP_EVENT_COUNT, }; @@ -2093,12 +2101,31 @@ union ec_response_get_next_data { uint32_t sysrq; } __packed; +union ec_response_get_next_data_v1 { + uint8_t key_matrix[16]; + + /* Unaligned */ + uint32_t host_event; + + uint32_t buttons; + uint32_t switches; + uint32_t sysrq; + uint32_t cec_events; + uint8_tcec_message[16]; +} __packed; + struct ec_response_get_next_event { uint8_t event_type; /* Followed by event data if any */ union ec_response_get_next_data data; } __packed; +struct ec_response_get_next_event_v1 { + uint8_t event_type; + /* Followed by event data if any */ + union ec_response_get_next_data_v1 data;
[PATCH v2 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi
This patchs adds the cec_notifier feature to the intel_hdmi part of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate between each HDMI ports. The changes will allow the i915 HDMI code to notify EDID and HPD changes to an eventual CEC adapter. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 12 3 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index dfd9588..2d65d56 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -23,6 +23,7 @@ config DRM_I915 select SYNC_FILE select IOSF_MBI select CRC32 + select CEC_CORE if CEC_NOTIFIER help Choose this option if you have a system that has "Intel Graphics Media Accelerator" or "HD Graphics" integrated graphics, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d436858..b50e51b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -39,6 +39,7 @@ #include #include #include +#include /** * __wait_for - magic wait macro @@ -1001,6 +1002,7 @@ struct intel_hdmi { bool has_audio; bool rgb_quant_range_selectable; struct intel_connector *attached_connector; + struct cec_notifier *notifier; }; struct intel_dp_mst_encoder; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1baef4a..e98103d 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) connected = true; } + cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid); + return connected; } @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); + if (status != connector_status_connected) + cec_notifier_phys_addr_invalidate(intel_hdmi->notifier); + return status; } @@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder, static void intel_hdmi_destroy(struct drm_connector *connector) { + if (intel_attached_hdmi(connector)->notifier) + cec_notifier_put(intel_attached_hdmi(connector)->notifier); kfree(to_intel_connector(connector)->detect_edid); drm_connector_cleanup(connector); kfree(connector); @@ -2358,6 +2366,10 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, u32 temp = I915_READ(PEG_BAND_GAP_DATA); I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); } + + intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name); + if (!intel_hdmi->notifier) + DRM_DEBUG_KMS("CEC notifier get failed\n"); } void intel_hdmi_init(struct drm_i915_private *dev_priv, -- 2.7.4
[PATCH v2 1/5] media: cec-notifier: Get notifier by device and connector name
In non device-tree world, we can need to get the notifier by the driver name directly and eventually defer probe if not yet created. This patch adds a variant of the get function by using the device name instead and will not create a notifier if not yet created. But the i915 driver exposes at least 2 HDMI connectors, this patch also adds the possibility to add a connector name tied to the notifier device to form a tuple and associate different CEC controllers for each HDMI connectors. Signed-off-by: Neil Armstrong --- drivers/media/cec/cec-notifier.c | 11 --- include/media/cec-notifier.h | 27 --- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c index 16dffa0..dd2078b 100644 --- a/drivers/media/cec/cec-notifier.c +++ b/drivers/media/cec/cec-notifier.c @@ -21,6 +21,7 @@ struct cec_notifier { struct list_head head; struct kref kref; struct device *dev; + const char *conn; struct cec_adapter *cec_adap; void (*callback)(struct cec_adapter *adap, u16 pa); @@ -30,13 +31,14 @@ struct cec_notifier { static LIST_HEAD(cec_notifiers); static DEFINE_MUTEX(cec_notifiers_lock); -struct cec_notifier *cec_notifier_get(struct device *dev) +struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn) { struct cec_notifier *n; mutex_lock(&cec_notifiers_lock); list_for_each_entry(n, &cec_notifiers, head) { - if (n->dev == dev) { + if (n->dev == dev && + (!conn || !strcmp(n->conn, conn))) { kref_get(&n->kref); mutex_unlock(&cec_notifiers_lock); return n; @@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev) if (!n) goto unlock; n->dev = dev; + if (conn) + n->conn = kstrdup(conn, GFP_KERNEL); n->phys_addr = CEC_PHYS_ADDR_INVALID; mutex_init(&n->lock); kref_init(&n->kref); @@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev) mutex_unlock(&cec_notifiers_lock); return n; } -EXPORT_SYMBOL_GPL(cec_notifier_get); +EXPORT_SYMBOL_GPL(cec_notifier_get_conn); static void cec_notifier_release(struct kref *kref) { @@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref) container_of(kref, struct cec_notifier, kref); list_del(&n->head); + kfree(n->conn); kfree(n); } diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h index cf0add7..814eeef 100644 --- a/include/media/cec-notifier.h +++ b/include/media/cec-notifier.h @@ -20,8 +20,10 @@ struct cec_notifier; #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) /** - * cec_notifier_get - find or create a new cec_notifier for the given device. + * cec_notifier_get_conn - find or create a new cec_notifier for the given + * device and connector tuple. * @dev: device that sends the events. + * @conn: the connector name from which the event occurs * * If a notifier for device @dev already exists, then increase the refcount * and return that notifier. @@ -31,7 +33,8 @@ struct cec_notifier; * * Return NULL if the memory could not be allocated. */ -struct cec_notifier *cec_notifier_get(struct device *dev); +struct cec_notifier *cec_notifier_get_conn(struct device *dev, + const char *conn); /** * cec_notifier_put - decrease refcount and delete when the refcount reaches 0. @@ -85,7 +88,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap, struct cec_notifier *notifier); #else -static inline struct cec_notifier *cec_notifier_get(struct device *dev) +static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev, +const char *conn) { /* A non-NULL pointer is expected on success */ return (struct cec_notifier *)0xdeadfeed; @@ -121,6 +125,23 @@ static inline void cec_register_cec_notifier(struct cec_adapter *adap, #endif /** + * cec_notifier_get - find or create a new cec_notifier for the given device. + * @dev: device that sends the events. + * + * If a notifier for device @dev already exists, then increase the refcount + * and return that notifier. + * + * If it doesn't exist, then allocate a new notifier struct and return a + * pointer to that new struct. + * + * Return NULL if the memory could not be allocated. + */ +static inline struct cec_notifier *cec_notifier_get(struct device *dev) +{ + return cec_notifier_get_conn(dev, NULL); +} + +/** * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID * * @n: the CEC notifier -- 2.7.4
[PATCH v2 0/5] Add ChromeOS EC CEC Support
Hi All, The new Google "Fizz" Intel-based ChromeOS device is gaining CEC support through it's Embedded Controller, to enable the Linux CEC Core to communicate with it and get the CEC Physical Address from the correct HDMI Connector, the following must be added/changed: - Add the CEC sub-device registration in the ChromeOS EC MFD Driver - Add the CEC related commands and events definitions into the EC MFD driver - Add a way to get a CEC notifier with it's (optional) connector name - Add the CEC notifier to the i915 HDMI driver - Add the proper ChromeOS EC CEC Driver The CEC notifier with the connector name is the tricky point, since even on Device-Tree platforms, there is no way to distinguish between multiple HDMI connectors from the same DRM driver. The solution I implemented is pretty simple and only adds an optional connector name to eventually distinguish an HDMI connector notifier from another if they share the same device. Feel free to comment this patchset ! Changes since v1: - Added cec_notifier_put to intel_hdmi - Fixed all small reported issues on the EC CEC driver - Moved the cec_notifier_get out of the #if .. #else .. #endif Changes since RFC: - Moved CEC sub-device registration after CEC commands and events definitions patch - Removed get_notifier_get_byname - Added CEC_CORE select into i915 Kconfig - Removed CEC driver fallback if notifier is not configured on HW, added explicit warn - Fixed CEC core return type on error - Moved to cros-ec-cec media platform directory - Use bus_find_device() to find the pci i915 device instead of get_notifier_get_byname() - Fix Logical Address setup - Added comment about HW support - Removed memset of msg structures Neil Armstrong (5): media: cec-notifier: Get notifier by device and connector name drm/i915: hdmi: add CEC notifier to intel_hdmi mfd: cros-ec: Introduce CEC commands and events definitions. mfd: cros_ec_dev: Add CEC sub-device registration media: platform: Add Chrome OS EC CEC driver drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_hdmi.c| 12 + drivers/media/cec/cec-notifier.c | 11 +- drivers/media/platform/Kconfig | 11 + drivers/media/platform/Makefile | 2 + drivers/media/platform/cros-ec-cec/Makefile | 1 + drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 335 +++ drivers/mfd/cros_ec_dev.c| 16 ++ drivers/platform/chrome/cros_ec_proto.c | 42 ++- include/linux/mfd/cros_ec.h | 2 +- include/linux/mfd/cros_ec_commands.h | 80 ++ include/media/cec-notifier.h | 27 +- 13 files changed, 526 insertions(+), 16 deletions(-) create mode 100644 drivers/media/platform/cros-ec-cec/Makefile create mode 100644 drivers/media/platform/cros-ec-cec/cros-ec-cec.c -- 2.7.4
Re: [PATCH v2 1/5] media: cec-notifier: Get notifier by device and connector name
On 05/15/2018 04:42 PM, Neil Armstrong wrote: > In non device-tree world, we can need to get the notifier by the driver > name directly and eventually defer probe if not yet created. > > This patch adds a variant of the get function by using the device name > instead and will not create a notifier if not yet created. > > But the i915 driver exposes at least 2 HDMI connectors, this patch also > adds the possibility to add a connector name tied to the notifier device > to form a tuple and associate different CEC controllers for each HDMI > connectors. The patch looks good, but I'm curious about this paragraph above. Was this tested with devices with more than one HDMI output? Or only on laptops with a single physical HDMI output? If there are two or more outputs then I guess it is the HW designer that decides with output gets CEC support? Regards, Hans > > Signed-off-by: Neil Armstrong > --- > drivers/media/cec/cec-notifier.c | 11 --- > include/media/cec-notifier.h | 27 --- > 2 files changed, 32 insertions(+), 6 deletions(-) > > diff --git a/drivers/media/cec/cec-notifier.c > b/drivers/media/cec/cec-notifier.c > index 16dffa0..dd2078b 100644 > --- a/drivers/media/cec/cec-notifier.c > +++ b/drivers/media/cec/cec-notifier.c > @@ -21,6 +21,7 @@ struct cec_notifier { > struct list_head head; > struct kref kref; > struct device *dev; > + const char *conn; > struct cec_adapter *cec_adap; > void (*callback)(struct cec_adapter *adap, u16 pa); > > @@ -30,13 +31,14 @@ struct cec_notifier { > static LIST_HEAD(cec_notifiers); > static DEFINE_MUTEX(cec_notifiers_lock); > > -struct cec_notifier *cec_notifier_get(struct device *dev) > +struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char > *conn) > { > struct cec_notifier *n; > > mutex_lock(&cec_notifiers_lock); > list_for_each_entry(n, &cec_notifiers, head) { > - if (n->dev == dev) { > + if (n->dev == dev && > + (!conn || !strcmp(n->conn, conn))) { > kref_get(&n->kref); > mutex_unlock(&cec_notifiers_lock); > return n; > @@ -46,6 +48,8 @@ struct cec_notifier *cec_notifier_get(struct device *dev) > if (!n) > goto unlock; > n->dev = dev; > + if (conn) > + n->conn = kstrdup(conn, GFP_KERNEL); > n->phys_addr = CEC_PHYS_ADDR_INVALID; > mutex_init(&n->lock); > kref_init(&n->kref); > @@ -54,7 +58,7 @@ struct cec_notifier *cec_notifier_get(struct device *dev) > mutex_unlock(&cec_notifiers_lock); > return n; > } > -EXPORT_SYMBOL_GPL(cec_notifier_get); > +EXPORT_SYMBOL_GPL(cec_notifier_get_conn); > > static void cec_notifier_release(struct kref *kref) > { > @@ -62,6 +66,7 @@ static void cec_notifier_release(struct kref *kref) > container_of(kref, struct cec_notifier, kref); > > list_del(&n->head); > + kfree(n->conn); > kfree(n); > } > > diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h > index cf0add7..814eeef 100644 > --- a/include/media/cec-notifier.h > +++ b/include/media/cec-notifier.h > @@ -20,8 +20,10 @@ struct cec_notifier; > #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) > > /** > - * cec_notifier_get - find or create a new cec_notifier for the given device. > + * cec_notifier_get_conn - find or create a new cec_notifier for the given > + * device and connector tuple. > * @dev: device that sends the events. > + * @conn: the connector name from which the event occurs > * > * If a notifier for device @dev already exists, then increase the refcount > * and return that notifier. > @@ -31,7 +33,8 @@ struct cec_notifier; > * > * Return NULL if the memory could not be allocated. > */ > -struct cec_notifier *cec_notifier_get(struct device *dev); > +struct cec_notifier *cec_notifier_get_conn(struct device *dev, > +const char *conn); > > /** > * cec_notifier_put - decrease refcount and delete when the refcount reaches > 0. > @@ -85,7 +88,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap, > struct cec_notifier *notifier); > > #else > -static inline struct cec_notifier *cec_notifier_get(struct device *dev) > +static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev, > + const char *conn) > { > /* A non-NULL pointer is expected on success */ > return (struct cec_notifier *)0xdeadfeed; > @@ -121,6 +125,23 @@ static inline void cec_register_cec_notifier(struct > cec_adapter *adap, > #endif > > /** > + * cec_notifier_get - find or create a new cec_notifier for the given device. > + * @dev: device that sends the events. > + * > + * If a notifier for device @dev already exists, then increase the refcoun
Re: [PATCH v2 2/5] drm/i915: hdmi: add CEC notifier to intel_hdmi
On 05/15/2018 04:42 PM, Neil Armstrong wrote: > This patchs adds the cec_notifier feature to the intel_hdmi part > of the i915 DRM driver. It uses the HDMI DRM connector name to differentiate > between each HDMI ports. > The changes will allow the i915 HDMI code to notify EDID and HPD changes > to an eventual CEC adapter. > > Signed-off-by: Neil Armstrong Reviewed-by: Hans Verkuil Thanks! Hans > --- > drivers/gpu/drm/i915/Kconfig | 1 + > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > drivers/gpu/drm/i915/intel_hdmi.c | 12 > 3 files changed, 15 insertions(+) > > diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig > index dfd9588..2d65d56 100644 > --- a/drivers/gpu/drm/i915/Kconfig > +++ b/drivers/gpu/drm/i915/Kconfig > @@ -23,6 +23,7 @@ config DRM_I915 > select SYNC_FILE > select IOSF_MBI > select CRC32 > + select CEC_CORE if CEC_NOTIFIER > help > Choose this option if you have a system that has "Intel Graphics > Media Accelerator" or "HD Graphics" integrated graphics, > diff --git a/drivers/gpu/drm/i915/intel_drv.h > b/drivers/gpu/drm/i915/intel_drv.h > index d436858..b50e51b 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -39,6 +39,7 @@ > #include > #include > #include > +#include > > /** > * __wait_for - magic wait macro > @@ -1001,6 +1002,7 @@ struct intel_hdmi { > bool has_audio; > bool rgb_quant_range_selectable; > struct intel_connector *attached_connector; > + struct cec_notifier *notifier; > }; > > struct intel_dp_mst_encoder; > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c > b/drivers/gpu/drm/i915/intel_hdmi.c > index 1baef4a..e98103d 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1868,6 +1868,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) > connected = true; > } > > + cec_notifier_set_phys_addr_from_edid(intel_hdmi->notifier, edid); > + > return connected; > } > > @@ -1876,6 +1878,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool > force) > { > enum drm_connector_status status; > struct drm_i915_private *dev_priv = to_i915(connector->dev); > + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > connector->base.id, connector->name); > @@ -1891,6 +1894,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool > force) > > intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > > + if (status != connector_status_connected) > + cec_notifier_phys_addr_invalidate(intel_hdmi->notifier); > + > return status; > } > > @@ -2031,6 +2037,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder > *encoder, > > static void intel_hdmi_destroy(struct drm_connector *connector) > { > + if (intel_attached_hdmi(connector)->notifier) > + cec_notifier_put(intel_attached_hdmi(connector)->notifier); > kfree(to_intel_connector(connector)->detect_edid); > drm_connector_cleanup(connector); > kfree(connector); > @@ -2358,6 +2366,10 @@ void intel_hdmi_init_connector(struct > intel_digital_port *intel_dig_port, > u32 temp = I915_READ(PEG_BAND_GAP_DATA); > I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); > } > + > + intel_hdmi->notifier = cec_notifier_get_conn(dev->dev, connector->name); > + if (!intel_hdmi->notifier) > + DRM_DEBUG_KMS("CEC notifier get failed\n"); > } > > void intel_hdmi_init(struct drm_i915_private *dev_priv, >
Re: [PATCH v2 3/5] mfd: cros-ec: Introduce CEC commands and events definitions.
On 05/15/2018 04:42 PM, Neil Armstrong wrote: > The EC can expose a CEC bus, this patch adds the CEC related definitions > needed by the cros-ec-cec driver. > Having a 16 byte mkbp event size makes it possible to send CEC > messages from the EC to the AP directly inside the mkbp event > instead of first doing a notification and then a read. > > Signed-off-by: Stefan Adolfsson > Signed-off-by: Neil Armstrong > --- > drivers/platform/chrome/cros_ec_proto.c | 42 + > include/linux/mfd/cros_ec.h | 2 +- > include/linux/mfd/cros_ec_commands.h| 80 > + > 3 files changed, 114 insertions(+), 10 deletions(-) > > diff --git a/drivers/platform/chrome/cros_ec_proto.c > b/drivers/platform/chrome/cros_ec_proto.c > index e7bbdf9..ba47f79 100644 > --- a/drivers/platform/chrome/cros_ec_proto.c > +++ b/drivers/platform/chrome/cros_ec_proto.c > @@ -504,29 +504,53 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device > *ec_dev, > } > EXPORT_SYMBOL(cros_ec_cmd_xfer_status); > > +static int get_next_event_xfer(struct cros_ec_device *ec_dev, > +struct cros_ec_command *msg, > +int version, uint32_t size) > +{ > + int ret; > + > + msg->version = version; > + msg->command = EC_CMD_GET_NEXT_EVENT; > + msg->insize = size; > + msg->outsize = 0; > + > + ret = cros_ec_cmd_xfer(ec_dev, msg); > + if (ret > 0) { > + ec_dev->event_size = ret - 1; > + memcpy(&ec_dev->event_data, msg->data, size); > + } > + > + return ret; > +} > + > static int get_next_event(struct cros_ec_device *ec_dev) > { > u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)]; > struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; > + static int cmd_version = 1; > int ret; > > + BUILD_BUG_ON(sizeof(union ec_response_get_next_data_v1) != 16); Use the define instead of hardcoding 16. I'm not really sure why you need this. If cec_message uses the right define for the array size (see my comment below), then this really can't go wrong, can it? > + > if (ec_dev->suspended) { > dev_dbg(ec_dev->dev, "Device suspended.\n"); > return -EHOSTDOWN; > } > > - msg->version = 0; > - msg->command = EC_CMD_GET_NEXT_EVENT; > - msg->insize = sizeof(ec_dev->event_data); > - msg->outsize = 0; > + if (cmd_version == 1) { > + ret = get_next_event_xfer(ec_dev, msg, cmd_version, > + sizeof(ec_dev->event_data)); > + if (ret != EC_RES_INVALID_VERSION) > + return ret; > > - ret = cros_ec_cmd_xfer(ec_dev, msg); > - if (ret > 0) { > - ec_dev->event_size = ret - 1; > - memcpy(&ec_dev->event_data, msg->data, > -sizeof(ec_dev->event_data)); > + /* Fallback to version 0 for future send attempts */ > + cmd_version = 0; > } > > + ret = get_next_event_xfer(ec_dev, msg, cmd_version, > + sizeof(struct ec_response_get_next_event)); > + > return ret; > } > > diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h > index 2d4e23c..f3415eb 100644 > --- a/include/linux/mfd/cros_ec.h > +++ b/include/linux/mfd/cros_ec.h > @@ -147,7 +147,7 @@ struct cros_ec_device { > bool mkbp_event_supported; > struct blocking_notifier_head event_notifier; > > - struct ec_response_get_next_event event_data; > + struct ec_response_get_next_event_v1 event_data; > int event_size; > u32 host_event_wake_mask; > }; > diff --git a/include/linux/mfd/cros_ec_commands.h > b/include/linux/mfd/cros_ec_commands.h > index f2edd99..18df466 100644 > --- a/include/linux/mfd/cros_ec_commands.h > +++ b/include/linux/mfd/cros_ec_commands.h > @@ -804,6 +804,8 @@ enum ec_feature_code { > EC_FEATURE_MOTION_SENSE_FIFO = 24, > /* EC has RTC feature that can be controlled by host commands */ > EC_FEATURE_RTC = 27, > + /* EC supports CEC commands */ > + EC_FEATURE_CEC = 35, > }; > > #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) > @@ -2078,6 +2080,12 @@ enum ec_mkbp_event { > /* EC sent a sysrq command */ > EC_MKBP_EVENT_SYSRQ = 6, > > + /* Notify the AP that something happened on CEC */ > + EC_MKBP_CEC_EVENT = 8, > + > + /* Send an incoming CEC message to the AP */ > + EC_MKBP_EVENT_CEC_MESSAGE = 9, > + > /* Number of MKBP events */ > EC_MKBP_EVENT_COUNT, > }; > @@ -2093,12 +2101,31 @@ union ec_response_get_next_data { > uint32_t sysrq; > } __packed; > > +union ec_response_get_next_data_v1 { > + uint8_t key_matrix[16]; > + > + /* Unaligned */ > + uint32_t host_event; > + > + uint32_t buttons; > + uint32_t switches; > + uint32_t sysrq; > + uint32_t cec_e
Re: [PATCH v2 4/5] mfd: cros_ec_dev: Add CEC sub-device registration
On 05/15/2018 04:42 PM, Neil Armstrong wrote: > The EC can expose a CEC bus, thus add the cros-ec-cec MFD sub-device > when the CEC feature bit is present. > > Signed-off-by: Neil Armstrong For what it is worth (not an MFD expert): Acked-by: Hans Verkuil Thanks! Hans > --- > drivers/mfd/cros_ec_dev.c | 16 > 1 file changed, 16 insertions(+) > > diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c > index eafd06f..57064ec 100644 > --- a/drivers/mfd/cros_ec_dev.c > +++ b/drivers/mfd/cros_ec_dev.c > @@ -383,6 +383,18 @@ static void cros_ec_sensors_register(struct cros_ec_dev > *ec) > kfree(msg); > } > > +static void cros_ec_cec_register(struct cros_ec_dev *ec) > +{ > + int ret; > + struct mfd_cell cec_cell = { > + .name = "cros-ec-cec", > + }; > + > + ret = mfd_add_devices(ec->dev, 0, &cec_cell, 1, NULL, 0, NULL); > + if (ret) > + dev_err(ec->dev, "failed to add EC CEC\n"); > +} > + > static int ec_device_probe(struct platform_device *pdev) > { > int retval = -ENOMEM; > @@ -422,6 +434,10 @@ static int ec_device_probe(struct platform_device *pdev) > if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) > cros_ec_sensors_register(ec); > > + /* check whether this EC handles CEC. */ > + if (cros_ec_check_features(ec, EC_FEATURE_CEC)) > + cros_ec_cec_register(ec); > + > /* Take control of the lightbar from the EC. */ > lb_manual_suspend_ctrl(ec, 1); > >