* Re: [PATCH v3 2/4] soc: qcom: Add GENI based QUP Wrapper driver [not found] ` <152037339742.218381.11498404122038956963-n1Xw8LXHxjTHt/MElyovVYaSKrA+ACpX0E9HWUfgJXw@public.gmane.org> @ 2018-03-08 6:46 ` Karthik Ramasubramanian [not found] ` <945b6c00-dde6-6ec7-4577-4cc0d034796b-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> 0 siblings, 1 reply; 4+ messages in thread From: Karthik Ramasubramanian @ 2018-03-08 6:46 UTC (permalink / raw) To: Stephen Boyd, Stephen Boyd, andy.gross-QSEj5FYQhm4dnm+yROfE0A, corbet-T1hC0tSOHrs, david.brown-QSEj5FYQhm4dnm+yROfE0A, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A, wsa-z923LK4zBo2bacvFa/9K2g, hch-jcswGhMUV9g, m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ, robin.murphy-5wv7dgnIgG8 Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Girish Mahadevan, acourbot-F7+t8E8rja9g9hUCZPvPmw, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, evgreen-F7+t8E8rja9g9hUCZPvPmw, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-serial-u79uwXL29TY76Z2rM5mHXA, jslaby-IBi9RG/b67k, Sagar Dharia On 3/6/2018 2:56 PM, Stephen Boyd wrote: > Quoting Karthik Ramasubramanian (2018-03-02 16:58:23) > >>>> + return iova; >>>> +} >>>> +EXPORT_SYMBOL(geni_se_tx_dma_prep); >>>> + >>>> +/** >>>> + * geni_se_rx_dma_prep() - Prepare the Serial Engine for RX DMA transfer >>>> + * @se: Pointer to the concerned Serial Engine. >>>> + * @buf: Pointer to the RX buffer. >>>> + * @len: Length of the RX buffer. >>>> + * >>>> + * This function is used to prepare the buffers for DMA RX. >>>> + * >>>> + * Return: Mapped DMA Address of the buffer on success, NULL on failure. >>>> + */ >>>> +dma_addr_t geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len) >>>> +{ >>>> + dma_addr_t iova; >>>> + struct geni_wrapper *wrapper = se->wrapper; >>>> + u32 val; >>>> + >>>> + iova = dma_map_single(wrapper->dev, buf, len, DMA_FROM_DEVICE); >>>> + if (dma_mapping_error(wrapper->dev, iova)) >>>> + return (dma_addr_t)NULL; >>> >>> Can't return a dma_mapping_error address to the caller and have them >>> figure it out? >> Earlier we used to return the DMA_ERROR_CODE which has been removed >> recently in arm64 architecture. If we return the dma_mapping_error, then >> the caller also needs the device which encountered the mapping error. >> The serial interface drivers can use their parent currently to resolve >> the mapping error. Once the wrapper starts mapping using IOMMU context >> bank, then the serial interface drivers do not know which device to use >> to know if there is an error. >> >> Having said that, the dma_ops suggestion might help with handling this >> situation. I will look into it further. > > Ok, thanks. > >>>> +{ >>>> + struct geni_wrapper *wrapper = se->wrapper; >>>> + >>>> + if (iova) >>>> + dma_unmap_single(wrapper->dev, iova, len, DMA_FROM_DEVICE); >>>> +} >>>> +EXPORT_SYMBOL(geni_se_rx_dma_unprep); >>> >>> Instead of having the functions exported, could we set the dma_ops on >>> all child devices of the wrapper that this driver populates and then >>> implement the DMA ops for those devices here? I assume that there's >>> never another DMA master between the wrapper and the serial engine, so I >>> think it would work. >> This suggestion looks like it will work. > > It would be a good idea to check with some other people on the dma_ops > suggestion. Maybe add the DMA mapping subsystem folks to help out here I have added the DMA mapping subsystem folks to help out here. To present an overview, we have a wrapper controller which is composed of several serial engines. The serial engines are programmed with UART, I2C or SPI protocol and support DMA transfer. When the serial engines perform DMA transfer, the wrapper controller device is used to perform the mapping. The reason wrapper device is used is because of IOMMU and there is only one IOMMU context bank to perform the translation for the entire wrapper controller. So the wrapper controller exports map and unmap functions to the individual protocol drivers. There is a suggestion to make the parent wrapper controller implement the dma_map_ops, instead of exported map/unmap functions and populate those dma_map_ops on all the children serial engines. Can you please provide your inputs regarding this suggestion? > > DMA MAPPING HELPERS > M: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org> > M: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> > R: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> > L: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org > > Regards, Karthik. -- Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <945b6c00-dde6-6ec7-4577-4cc0d034796b-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>]
* Re: [PATCH v3 2/4] soc: qcom: Add GENI based QUP Wrapper driver [not found] ` <945b6c00-dde6-6ec7-4577-4cc0d034796b-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> @ 2018-03-08 13:24 ` Robin Murphy [not found] ` <8567be1b-1431-4f1d-cb41-6a7eaa434438-5wv7dgnIgG8@public.gmane.org> 0 siblings, 1 reply; 4+ messages in thread From: Robin Murphy @ 2018-03-08 13:24 UTC (permalink / raw) To: Karthik Ramasubramanian, Stephen Boyd, Stephen Boyd, andy.gross-QSEj5FYQhm4dnm+yROfE0A, corbet-T1hC0tSOHrs, david.brown-QSEj5FYQhm4dnm+yROfE0A, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A, wsa-z923LK4zBo2bacvFa/9K2g, hch-jcswGhMUV9g, m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Girish Mahadevan, acourbot-F7+t8E8rja9g9hUCZPvPmw, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, evgreen-F7+t8E8rja9g9hUCZPvPmw, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-serial-u79uwXL29TY76Z2rM5mHXA, jslaby-IBi9RG/b67k, Sagar Dharia On 08/03/18 06:46, Karthik Ramasubramanian wrote: > > > On 3/6/2018 2:56 PM, Stephen Boyd wrote: >> Quoting Karthik Ramasubramanian (2018-03-02 16:58:23) >> >>>>> + return iova; >>>>> +} >>>>> +EXPORT_SYMBOL(geni_se_tx_dma_prep); >>>>> + >>>>> +/** >>>>> + * geni_se_rx_dma_prep() - Prepare the Serial Engine for RX DMA >>>>> transfer >>>>> + * @se: Pointer to the concerned Serial >>>>> Engine. >>>>> + * @buf: Pointer to the RX buffer. >>>>> + * @len: Length of the RX buffer. >>>>> + * >>>>> + * This function is used to prepare the buffers for DMA RX. >>>>> + * >>>>> + * Return: Mapped DMA Address of the buffer on success, NULL on >>>>> failure. >>>>> + */ >>>>> +dma_addr_t geni_se_rx_dma_prep(struct geni_se *se, void *buf, >>>>> size_t len) >>>>> +{ >>>>> + dma_addr_t iova; >>>>> + struct geni_wrapper *wrapper = se->wrapper; >>>>> + u32 val; >>>>> + >>>>> + iova = dma_map_single(wrapper->dev, buf, len, >>>>> DMA_FROM_DEVICE); >>>>> + if (dma_mapping_error(wrapper->dev, iova)) >>>>> + return (dma_addr_t)NULL; >>>> >>>> Can't return a dma_mapping_error address to the caller and have them >>>> figure it out? >>> Earlier we used to return the DMA_ERROR_CODE which has been removed >>> recently in arm64 architecture. If we return the dma_mapping_error, then >>> the caller also needs the device which encountered the mapping error. >>> The serial interface drivers can use their parent currently to resolve >>> the mapping error. Once the wrapper starts mapping using IOMMU context >>> bank, then the serial interface drivers do not know which device to use >>> to know if there is an error. >>> >>> Having said that, the dma_ops suggestion might help with handling this >>> situation. I will look into it further. >> >> Ok, thanks. >> >>>>> +{ >>>>> + struct geni_wrapper *wrapper = se->wrapper; >>>>> + >>>>> + if (iova) >>>>> + dma_unmap_single(wrapper->dev, iova, len, >>>>> DMA_FROM_DEVICE); >>>>> +} >>>>> +EXPORT_SYMBOL(geni_se_rx_dma_unprep); >>>> >>>> Instead of having the functions exported, could we set the dma_ops on >>>> all child devices of the wrapper that this driver populates and then >>>> implement the DMA ops for those devices here? I assume that there's >>>> never another DMA master between the wrapper and the serial engine, >>>> so I >>>> think it would work. >>> This suggestion looks like it will work. >> >> It would be a good idea to check with some other people on the dma_ops >> suggestion. Maybe add the DMA mapping subsystem folks to help out here > I have added the DMA mapping subsystem folks to help out here. > > To present an overview, we have a wrapper controller which is composed > of several serial engines. The serial engines are programmed with UART, > I2C or SPI protocol and support DMA transfer. When the serial engines > perform DMA transfer, the wrapper controller device is used to perform > the mapping. The reason wrapper device is used is because of IOMMU and > there is only one IOMMU context bank to perform the translation for the > entire wrapper controller. So the wrapper controller exports map and > unmap functions to the individual protocol drivers. > > There is a suggestion to make the parent wrapper controller implement > the dma_map_ops, instead of exported map/unmap functions and populate > those dma_map_ops on all the children serial engines. Can you please > provide your inputs regarding this suggestion? Implementing dma_map_ops inside a driver for real hardware is almost always the wrong thing to do. Based on what I could infer about the hardware from looking through the whole series in the linux-arm-msm archive, this is probably more like a multi-channel DMA controller where each "channel" has a configurable serial interface on the other end, as opposed to an actual bus where the serial engines are individually distinct AHB masters routed through the wrapper. If that's true, then using the QUP platform device for DMA API calls is the appropriate thing to do. Personally I'd be inclined not to abstract the dma_{map,unmap} calls at all, and just have the protocol drivers make them directly using dev->parent/wrapper->dev/whatever, but if you do want to abstract those then just give the abstraction a saner interface, i.e. pass the DMA handle by reference and return a regular int for error/success status. Robin. _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <8567be1b-1431-4f1d-cb41-6a7eaa434438-5wv7dgnIgG8@public.gmane.org>]
* Re: [PATCH v3 2/4] soc: qcom: Add GENI based QUP Wrapper driver [not found] ` <8567be1b-1431-4f1d-cb41-6a7eaa434438-5wv7dgnIgG8@public.gmane.org> @ 2018-03-08 14:41 ` Christoph Hellwig 2018-03-08 18:18 ` Karthik Ramasubramanian 1 sibling, 0 replies; 4+ messages in thread From: Christoph Hellwig @ 2018-03-08 14:41 UTC (permalink / raw) To: Robin Murphy Cc: mark.rutland-5wv7dgnIgG8, wsa-z923LK4zBo2bacvFa/9K2g, david.brown-QSEj5FYQhm4dnm+yROfE0A, Karthik Ramasubramanian, linux-i2c-u79uwXL29TY76Z2rM5mHXA, hch-jcswGhMUV9g, corbet-T1hC0tSOHrs, linux-doc-u79uwXL29TY76Z2rM5mHXA, evgreen-F7+t8E8rja9g9hUCZPvPmw, linux-serial-u79uwXL29TY76Z2rM5mHXA, jslaby-IBi9RG/b67k, andy.gross-QSEj5FYQhm4dnm+yROfE0A, Stephen Boyd, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Stephen Boyd, robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Sagar Dharia, Girish Mahadevan, acourbot-F7+t8E8rja9g9hUCZPvPmw, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA On Thu, Mar 08, 2018 at 01:24:45PM +0000, Robin Murphy wrote: > Implementing dma_map_ops inside a driver for real hardware is almost always > the wrong thing to do. Agreed. dma_map_ops should be a platform decision based on the bus. Even our dma_virt_ops basically just works around bad driver layering. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3 2/4] soc: qcom: Add GENI based QUP Wrapper driver [not found] ` <8567be1b-1431-4f1d-cb41-6a7eaa434438-5wv7dgnIgG8@public.gmane.org> 2018-03-08 14:41 ` Christoph Hellwig @ 2018-03-08 18:18 ` Karthik Ramasubramanian 1 sibling, 0 replies; 4+ messages in thread From: Karthik Ramasubramanian @ 2018-03-08 18:18 UTC (permalink / raw) To: Robin Murphy, Stephen Boyd, Stephen Boyd, andy.gross-QSEj5FYQhm4dnm+yROfE0A, corbet-T1hC0tSOHrs, david.brown-QSEj5FYQhm4dnm+yROfE0A, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A, wsa-z923LK4zBo2bacvFa/9K2g, hch-jcswGhMUV9g, m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Girish Mahadevan, acourbot-F7+t8E8rja9g9hUCZPvPmw, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, evgreen-F7+t8E8rja9g9hUCZPvPmw, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-serial-u79uwXL29TY76Z2rM5mHXA, jslaby-IBi9RG/b67k, Sagar Dharia On 3/8/2018 6:24 AM, Robin Murphy wrote: > On 08/03/18 06:46, Karthik Ramasubramanian wrote: >> >> >> On 3/6/2018 2:56 PM, Stephen Boyd wrote: >>> Quoting Karthik Ramasubramanian (2018-03-02 16:58:23) >>> >>>>>> + return iova; >>>>>> +} >>>>>> +EXPORT_SYMBOL(geni_se_tx_dma_prep); >>>>>> + >>>>>> +/** >>>>>> + * geni_se_rx_dma_prep() - Prepare the Serial Engine for RX DMA >>>>>> transfer >>>>>> + * @se: Pointer to the concerned Serial >>>>>> Engine. >>>>>> + * @buf: Pointer to the RX buffer. >>>>>> + * @len: Length of the RX buffer. >>>>>> + * >>>>>> + * This function is used to prepare the buffers for DMA RX. >>>>>> + * >>>>>> + * Return: Mapped DMA Address of the buffer on success, NULL on >>>>>> failure. >>>>>> + */ >>>>>> +dma_addr_t geni_se_rx_dma_prep(struct geni_se *se, void *buf, >>>>>> size_t len) >>>>>> +{ >>>>>> + dma_addr_t iova; >>>>>> + struct geni_wrapper *wrapper = se->wrapper; >>>>>> + u32 val; >>>>>> + >>>>>> + iova = dma_map_single(wrapper->dev, buf, len, >>>>>> DMA_FROM_DEVICE); >>>>>> + if (dma_mapping_error(wrapper->dev, iova)) >>>>>> + return (dma_addr_t)NULL; >>>>> >>>>> Can't return a dma_mapping_error address to the caller and have them >>>>> figure it out? >>>> Earlier we used to return the DMA_ERROR_CODE which has been removed >>>> recently in arm64 architecture. If we return the dma_mapping_error, >>>> then >>>> the caller also needs the device which encountered the mapping error. >>>> The serial interface drivers can use their parent currently to resolve >>>> the mapping error. Once the wrapper starts mapping using IOMMU context >>>> bank, then the serial interface drivers do not know which device to use >>>> to know if there is an error. >>>> >>>> Having said that, the dma_ops suggestion might help with handling this >>>> situation. I will look into it further. >>> >>> Ok, thanks. >>> >>>>>> +{ >>>>>> + struct geni_wrapper *wrapper = se->wrapper; >>>>>> + >>>>>> + if (iova) >>>>>> + dma_unmap_single(wrapper->dev, iova, len, >>>>>> DMA_FROM_DEVICE); >>>>>> +} >>>>>> +EXPORT_SYMBOL(geni_se_rx_dma_unprep); >>>>> >>>>> Instead of having the functions exported, could we set the dma_ops on >>>>> all child devices of the wrapper that this driver populates and then >>>>> implement the DMA ops for those devices here? I assume that there's >>>>> never another DMA master between the wrapper and the serial engine, >>>>> so I >>>>> think it would work. >>>> This suggestion looks like it will work. >>> >>> It would be a good idea to check with some other people on the dma_ops >>> suggestion. Maybe add the DMA mapping subsystem folks to help out here >> I have added the DMA mapping subsystem folks to help out here. >> >> To present an overview, we have a wrapper controller which is composed >> of several serial engines. The serial engines are programmed with >> UART, I2C or SPI protocol and support DMA transfer. When the serial >> engines perform DMA transfer, the wrapper controller device is used to >> perform the mapping. The reason wrapper device is used is because of >> IOMMU and there is only one IOMMU context bank to perform the >> translation for the entire wrapper controller. So the wrapper >> controller exports map and unmap functions to the individual protocol >> drivers. >> >> There is a suggestion to make the parent wrapper controller implement >> the dma_map_ops, instead of exported map/unmap functions and populate >> those dma_map_ops on all the children serial engines. Can you please >> provide your inputs regarding this suggestion? > > Implementing dma_map_ops inside a driver for real hardware is almost > always the wrong thing to do. > > Based on what I could infer about the hardware from looking through the > whole series in the linux-arm-msm archive, this is probably more like a > multi-channel DMA controller where each "channel" has a configurable > serial interface on the other end, as opposed to an actual bus where the > serial engines are individually distinct AHB masters routed through the > wrapper. If that's true, then using the QUP platform device for DMA API > calls is the appropriate thing to do. Personally I'd be inclined not to > abstract the dma_{map,unmap} calls at all, and just have the protocol > drivers make them directly using dev->parent/wrapper->dev/whatever, but > if you do want to abstract those then just give the abstraction a saner > interface, i.e. pass the DMA handle by reference and return a regular > int for error/success status. > > Robin. Thank you Robin & Christoph for your inputs. The wrapper driver used to provide the recommended abstraction until v2 of this patch series. In v3 it was tweaked to address a comment. If there are no objections, I will revive it back. Regards, Karthik. -- Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-03-08 18:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1519781889-16117-1-git-send-email-kramasub@codeaurora.org>
[not found] ` <1519781889-16117-3-git-send-email-kramasub@codeaurora.org>
[not found] ` <152002326567.108663.16836885081217739460@swboyd.mtv.corp.google.com>
[not found] ` <4ac213a6-081f-72c1-c9c8-6994786285c9@codeaurora.org>
[not found] ` <152037339742.218381.11498404122038956963@swboyd.mtv.corp.google.com>
[not found] ` <152037339742.218381.11498404122038956963-n1Xw8LXHxjTHt/MElyovVYaSKrA+ACpX0E9HWUfgJXw@public.gmane.org>
2018-03-08 6:46 ` [PATCH v3 2/4] soc: qcom: Add GENI based QUP Wrapper driver Karthik Ramasubramanian
[not found] ` <945b6c00-dde6-6ec7-4577-4cc0d034796b-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-08 13:24 ` Robin Murphy
[not found] ` <8567be1b-1431-4f1d-cb41-6a7eaa434438-5wv7dgnIgG8@public.gmane.org>
2018-03-08 14:41 ` Christoph Hellwig
2018-03-08 18:18 ` Karthik Ramasubramanian
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).