All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/18]  Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
@ 2016-05-25 16:06 ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

Hi Vinod / Maxime / Bjorn,

This patchset adds support for the Flexible Direct Memory Access (FDMA) core
found on STi chipsets from STMicroelectronics. The FDMA is a slim (xp70) core CPU
with a dedicated firmware. It is a general purpose DMA controller supporting
16 independent channels and data can be moved from memory to memory or between
memory and paced latency critical real time targets.

After some discussion with the DT maintainers I've removed the firmware
name from DT, and now generate the name based on the compatible string.
This is in keeping with how most other kernel drivers request firmware, and avoids
a new DT firmware name or fdma id binding.

I've also dropped the xbar support for the moment, as I believe it should be
re-worked based on some of the xbar API's that TI recently added. As requested
I've also split it into smaller patches to help with a faster review.

V3 also included some updates to the ASoC DT documentation, and extra DT patches
for Maximes STi DT tree to enable ASoC on STi407 based platforms using the fdma
driver.

v4 includes a new xp70 rproc driver for loading the XP70 elf firmware. This
enables us to use the generic rproc elf loading code. This has deliberately not
been implemented as a platform_driver, to avoid having to have double mappings of
I/O memory from two device drivers, and also to ensure that the DT node reflects
the actual hardware rather than Linux subsystems. The xp70 slimcore is the basis
for various pieces of IP in STi chipsets and the intention is that other drivers
(demux, display) can also be migrated over to using the xp70 rproc for their
elf firmware loading and start/stop control.

regards,

Peter.

Changes since v3:
 - Remove elf loading code from fdma driver (Vinod)
 - Remove fdma_ prefix for clock names (Arnd)
 - Make _xlate use dma_get_any_channel rather than request_channel (Arnd)
 - Make a common function for _prep_ routines (Vinod)
 - Make driver depend on COMPILE_TEST (Arnd)
 - Remove unnecessary st_fdma_filter_fn (Arnd)
 - Enable FDMA as a module (Arnd)
 - Drop fdma_ clock prefix (Arnd)
 - Fix description as well as example for st, prefix (Arnd)
 - Remove string concatenation from fdma register macros to ease grep'ability (Arnd)
 - Add a XP70 rproc driver for ELF firmware loading and start/stop control (Peter)
 - Add myself as a author of the driver (Peter)

Changes since v2:
 - Change to dma-controller (Arnd)
 - Remove platform data header file and simplifiy code (Arnd)
 - Remove FW_LOADER_USER_HELPER_FALLBACK and rework firmware loading to device config (Vinod)
 - Use SET_RUNTIME_PM_OPS helpers (Vinod)
 - Remove fdma-id dt prop and use compatibles to generate different fdma firmware names (Arnd / Lee)
 - Add sti-asoc-card DT nodes and pinmux config for uniperif player & reader (Peter)
 - Update sti-asoc-card DT binding documentation (Peter)
 - Enable STi audio drivers in multi_v7_defconfig (Peter)

Changes since v1:
 - split into smaller patches for easier / faster review (Vinod)
 - new fill_hw_mode() with common code (Vinod)
 - new config_reqctrl() called from *_prep() instead of device_config cb (Vinod)
 - fdma-xbar support removed (Peter)
 - rework firmware name mechanism so fwname isn't in DT (Peter / Lee)
 - st_fdma_seg_to_mem can be static (Paul)
 - EXPORT_SYMBOL st_fdma_filter_fn not required (Paul)
 - s/channel/channels (vinod)
 - better describe "Must be <3>" (vinod)
 - sizeof(*ehdr) (vinod)
 - print values on error debug (vinod)
 - empty line (Vinod)
 - Update to -EIO (Vinod)
 - Make st_fdma tristate (Paul)
 - Remove __exit tag from .remove (Maxime)
 - Update MAINTAINERS rule to fdma* (Lee)
 - Unit address should match reg property (Lee)

Peter Griffin (18):
  dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
    documentation
  dmaengine: st_fdma:  Add STMicroelectronics FDMA driver header file
  dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
  dmaengine: st_fdma: Add xp70 firmware loading mechanism.
  dmaengine: st_fdma: Add fdma suspend and resume callbacks.
  ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
  MAINTAINERS: Add FDMA driver files to STi section.
  ARM: multi_v7_defconfig: Enable STi FDMA driver
  ASoC: sti: Update DT example to match the driver code
  ASoC: sti: Update example to include assigned-clocks and mclk-fs
  ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
  ARM: DT: STiH407: Add i2s_out pinctrl configuration
  ARM: DT: STiH407: Add i2s_in pinctrl configuration
  ARM: DT: STiH407: Add spdif_out pinctrl config
  ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
  ARM: STi: DT: STiH407: Add uniperif player dt nodes
  ARM: STi: DT: STiH407: Add uniperif reader dt nodes
  ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card

 Documentation/devicetree/bindings/dma/st_fdma.txt  |   87 ++
 .../devicetree/bindings/sound/st,sti-asoc-card.txt |   22 +-
 MAINTAINERS                                        |    1 +
 arch/arm/boot/dts/stih407-family.dtsi              |  164 +++
 arch/arm/boot/dts/stih407-pinctrl.dtsi             |   55 +
 arch/arm/boot/dts/stihxxx-b2120.dtsi               |   40 +
 arch/arm/configs/multi_v7_defconfig                |    4 +
 drivers/dma/Kconfig                                |   12 +
 drivers/dma/Makefile                               |    1 +
 drivers/dma/st_fdma.c                              | 1203 ++++++++++++++++++++
 drivers/dma/st_fdma.h                              |  281 +++++
 11 files changed, 1863 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
 create mode 100644 drivers/dma/st_fdma.c
 create mode 100644 drivers/dma/st_fdma.h

-- 
1.9.1

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

* [PATCH 00/18] Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
@ 2016-05-25 16:06 ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vinod / Maxime / Bjorn,

This patchset adds support for the Flexible Direct Memory Access (FDMA) core
found on STi chipsets from STMicroelectronics. The FDMA is a slim (xp70) core CPU
with a dedicated firmware. It is a general purpose DMA controller supporting
16 independent channels and data can be moved from memory to memory or between
memory and paced latency critical real time targets.

After some discussion with the DT maintainers I've removed the firmware
name from DT, and now generate the name based on the compatible string.
This is in keeping with how most other kernel drivers request firmware, and avoids
a new DT firmware name or fdma id binding.

I've also dropped the xbar support for the moment, as I believe it should be
re-worked based on some of the xbar API's that TI recently added. As requested
I've also split it into smaller patches to help with a faster review.

V3 also included some updates to the ASoC DT documentation, and extra DT patches
for Maximes STi DT tree to enable ASoC on STi407 based platforms using the fdma
driver.

v4 includes a new xp70 rproc driver for loading the XP70 elf firmware. This
enables us to use the generic rproc elf loading code. This has deliberately not
been implemented as a platform_driver, to avoid having to have double mappings of
I/O memory from two device drivers, and also to ensure that the DT node reflects
the actual hardware rather than Linux subsystems. The xp70 slimcore is the basis
for various pieces of IP in STi chipsets and the intention is that other drivers
(demux, display) can also be migrated over to using the xp70 rproc for their
elf firmware loading and start/stop control.

regards,

Peter.

Changes since v3:
 - Remove elf loading code from fdma driver (Vinod)
 - Remove fdma_ prefix for clock names (Arnd)
 - Make _xlate use dma_get_any_channel rather than request_channel (Arnd)
 - Make a common function for _prep_ routines (Vinod)
 - Make driver depend on COMPILE_TEST (Arnd)
 - Remove unnecessary st_fdma_filter_fn (Arnd)
 - Enable FDMA as a module (Arnd)
 - Drop fdma_ clock prefix (Arnd)
 - Fix description as well as example for st, prefix (Arnd)
 - Remove string concatenation from fdma register macros to ease grep'ability (Arnd)
 - Add a XP70 rproc driver for ELF firmware loading and start/stop control (Peter)
 - Add myself as a author of the driver (Peter)

Changes since v2:
 - Change to dma-controller (Arnd)
 - Remove platform data header file and simplifiy code (Arnd)
 - Remove FW_LOADER_USER_HELPER_FALLBACK and rework firmware loading to device config (Vinod)
 - Use SET_RUNTIME_PM_OPS helpers (Vinod)
 - Remove fdma-id dt prop and use compatibles to generate different fdma firmware names (Arnd / Lee)
 - Add sti-asoc-card DT nodes and pinmux config for uniperif player & reader (Peter)
 - Update sti-asoc-card DT binding documentation (Peter)
 - Enable STi audio drivers in multi_v7_defconfig (Peter)

Changes since v1:
 - split into smaller patches for easier / faster review (Vinod)
 - new fill_hw_mode() with common code (Vinod)
 - new config_reqctrl() called from *_prep() instead of device_config cb (Vinod)
 - fdma-xbar support removed (Peter)
 - rework firmware name mechanism so fwname isn't in DT (Peter / Lee)
 - st_fdma_seg_to_mem can be static (Paul)
 - EXPORT_SYMBOL st_fdma_filter_fn not required (Paul)
 - s/channel/channels (vinod)
 - better describe "Must be <3>" (vinod)
 - sizeof(*ehdr) (vinod)
 - print values on error debug (vinod)
 - empty line (Vinod)
 - Update to -EIO (Vinod)
 - Make st_fdma tristate (Paul)
 - Remove __exit tag from .remove (Maxime)
 - Update MAINTAINERS rule to fdma* (Lee)
 - Unit address should match reg property (Lee)

Peter Griffin (18):
  dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
    documentation
  dmaengine: st_fdma:  Add STMicroelectronics FDMA driver header file
  dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
  dmaengine: st_fdma: Add xp70 firmware loading mechanism.
  dmaengine: st_fdma: Add fdma suspend and resume callbacks.
  ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
  MAINTAINERS: Add FDMA driver files to STi section.
  ARM: multi_v7_defconfig: Enable STi FDMA driver
  ASoC: sti: Update DT example to match the driver code
  ASoC: sti: Update example to include assigned-clocks and mclk-fs
  ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
  ARM: DT: STiH407: Add i2s_out pinctrl configuration
  ARM: DT: STiH407: Add i2s_in pinctrl configuration
  ARM: DT: STiH407: Add spdif_out pinctrl config
  ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
  ARM: STi: DT: STiH407: Add uniperif player dt nodes
  ARM: STi: DT: STiH407: Add uniperif reader dt nodes
  ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card

 Documentation/devicetree/bindings/dma/st_fdma.txt  |   87 ++
 .../devicetree/bindings/sound/st,sti-asoc-card.txt |   22 +-
 MAINTAINERS                                        |    1 +
 arch/arm/boot/dts/stih407-family.dtsi              |  164 +++
 arch/arm/boot/dts/stih407-pinctrl.dtsi             |   55 +
 arch/arm/boot/dts/stihxxx-b2120.dtsi               |   40 +
 arch/arm/configs/multi_v7_defconfig                |    4 +
 drivers/dma/Kconfig                                |   12 +
 drivers/dma/Makefile                               |    1 +
 drivers/dma/st_fdma.c                              | 1203 ++++++++++++++++++++
 drivers/dma/st_fdma.h                              |  281 +++++
 11 files changed, 1863 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
 create mode 100644 drivers/dma/st_fdma.c
 create mode 100644 drivers/dma/st_fdma.h

-- 
1.9.1

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

* [PATCH v4 00/18] Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

Hi Vinod / Maxime / Bjorn,

This patchset adds support for the Flexible Direct Memory Access (FDMA) core
found on STi chipsets from STMicroelectronics. The FDMA is a slim (xp70) core CPU
with a dedicated firmware. It is a general purpose DMA controller supporting
16 independent channels and data can be moved from memory to memory or between
memory and paced latency critical real time targets.

After some discussion with the DT maintainers I've removed the firmware
name from DT, and now generate the name based on the compatible string.
This is in keeping with how most other kernel drivers request firmware, and avoids
a new DT firmware name or fdma id binding.

I've also dropped the xbar support for the moment, as I believe it should be
re-worked based on some of the xbar API's that TI recently added. As requested
I've also split it into smaller patches to help with a faster review.

V3 also included some updates to the ASoC DT documentation, and extra DT patches
for Maximes STi DT tree to enable ASoC on STi407 based platforms using the fdma
driver.

v4 includes a new xp70 rproc driver for loading the XP70 elf firmware. This
enables us to use the generic rproc elf loading code. This has deliberately not
been implemented as a platform_driver, to avoid having to have double mappings of
I/O memory from two device drivers, and also to ensure that the DT node reflects
the actual hardware rather than Linux subsystems. The xp70 slimcore is the basis
for various pieces of IP in STi chipsets and the intention is that other drivers
(demux, display) can also be migrated over to using the xp70 rproc for their
elf firmware loading and start/stop control.

regards,

Peter.

Changes since v3:
 - Remove elf loading code from fdma driver (Vinod)
 - Remove fdma_ prefix for clock names (Arnd)
 - Make _xlate use dma_get_any_channel rather than request_channel (Arnd)
 - Make a common function for _prep_ routines (Vinod)
 - Make driver depend on COMPILE_TEST (Arnd)
 - Remove unnecessary st_fdma_filter_fn (Arnd)
 - Enable FDMA as a module (Arnd)
 - Drop fdma_ clock prefix (Arnd)
 - Fix description as well as example for st, prefix (Arnd)
 - Remove string concatenation from fdma register macros to ease grep'ability (Arnd)
 - Add a XP70 rproc driver for ELF firmware loading and start/stop control (Peter)
 - Add myself as a author of the driver (Peter)

Changes since v2:
 - Change to dma-controller (Arnd)
 - Remove platform data header file and simplifiy code (Arnd)
 - Remove FW_LOADER_USER_HELPER_FALLBACK and rework firmware loading to device config (Vinod)
 - Use SET_RUNTIME_PM_OPS helpers (Vinod)
 - Remove fdma-id dt prop and use compatibles to generate different fdma firmware names (Arnd / Lee)
 - Add sti-asoc-card DT nodes and pinmux config for uniperif player & reader (Peter)
 - Update sti-asoc-card DT binding documentation (Peter)
 - Enable STi audio drivers in multi_v7_defconfig (Peter)

Changes since v1:
 - split into smaller patches for easier / faster review (Vinod)
 - new fill_hw_mode() with common code (Vinod)
 - new config_reqctrl() called from *_prep() instead of device_config cb (Vinod)
 - fdma-xbar support removed (Peter)
 - rework firmware name mechanism so fwname isn't in DT (Peter / Lee)
 - st_fdma_seg_to_mem can be static (Paul)
 - EXPORT_SYMBOL st_fdma_filter_fn not required (Paul)
 - s/channel/channels (vinod)
 - better describe "Must be <3>" (vinod)
 - sizeof(*ehdr) (vinod)
 - print values on error debug (vinod)
 - empty line (Vinod)
 - Update to -EIO (Vinod)
 - Make st_fdma tristate (Paul)
 - Remove __exit tag from .remove (Maxime)
 - Update MAINTAINERS rule to fdma* (Lee)
 - Unit address should match reg property (Lee)

Peter Griffin (18):
  remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
  ARM: multi_v7_defconfig: enable st xp70 rproc driver.
  MAINTAINERS: Add st xp70 rproc driver to STi section.
  dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
    documentation
  dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
  dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
  ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
  MAINTAINERS: Add FDMA driver files to STi section.
  ARM: multi_v7_defconfig: Enable STi FDMA driver
  ASoC: sti: Update DT example to match the driver code
  ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
  ARM: DT: STiH407: Add i2s_out pinctrl configuration
  ARM: DT: STiH407: Add i2s_in pinctrl configuration
  ARM: DT: STiH407: Add spdif_out pinctrl config
  ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
  ARM: STi: DT: STiH407: Add uniperif player dt nodes
  ARM: STi: DT: STiH407: Add uniperif reader dt nodes
  ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card

 Documentation/devicetree/bindings/dma/st_fdma.txt  |  87 ++
 .../devicetree/bindings/sound/st,sti-asoc-card.txt |  20 +-
 MAINTAINERS                                        |   3 +
 arch/arm/boot/dts/stih407-family.dtsi              | 165 ++++
 arch/arm/boot/dts/stih407-pinctrl.dtsi             |  55 ++
 arch/arm/boot/dts/stihxxx-b2120.dtsi               |  40 +
 arch/arm/configs/multi_v7_defconfig                |   5 +
 drivers/dma/Kconfig                                |  12 +
 drivers/dma/Makefile                               |   1 +
 drivers/dma/st_fdma.c                              | 882 +++++++++++++++++++++
 drivers/dma/st_fdma.h                              | 243 ++++++
 drivers/remoteproc/Kconfig                         |   8 +
 drivers/remoteproc/Makefile                        |   1 +
 drivers/remoteproc/st_xp70_rproc.c                 | 380 +++++++++
 include/linux/remoteproc/st_xp70_rproc.h           |  56 ++
 15 files changed, 1948 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
 create mode 100644 drivers/dma/st_fdma.c
 create mode 100644 drivers/dma/st_fdma.h
 create mode 100644 drivers/remoteproc/st_xp70_rproc.c
 create mode 100644 include/linux/remoteproc/st_xp70_rproc.h

-- 
1.9.1

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

* [PATCH v4 00/18] Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vinod / Maxime / Bjorn,

This patchset adds support for the Flexible Direct Memory Access (FDMA) core
found on STi chipsets from STMicroelectronics. The FDMA is a slim (xp70) core CPU
with a dedicated firmware. It is a general purpose DMA controller supporting
16 independent channels and data can be moved from memory to memory or between
memory and paced latency critical real time targets.

After some discussion with the DT maintainers I've removed the firmware
name from DT, and now generate the name based on the compatible string.
This is in keeping with how most other kernel drivers request firmware, and avoids
a new DT firmware name or fdma id binding.

I've also dropped the xbar support for the moment, as I believe it should be
re-worked based on some of the xbar API's that TI recently added. As requested
I've also split it into smaller patches to help with a faster review.

V3 also included some updates to the ASoC DT documentation, and extra DT patches
for Maximes STi DT tree to enable ASoC on STi407 based platforms using the fdma
driver.

v4 includes a new xp70 rproc driver for loading the XP70 elf firmware. This
enables us to use the generic rproc elf loading code. This has deliberately not
been implemented as a platform_driver, to avoid having to have double mappings of
I/O memory from two device drivers, and also to ensure that the DT node reflects
the actual hardware rather than Linux subsystems. The xp70 slimcore is the basis
for various pieces of IP in STi chipsets and the intention is that other drivers
(demux, display) can also be migrated over to using the xp70 rproc for their
elf firmware loading and start/stop control.

regards,

Peter.

Changes since v3:
 - Remove elf loading code from fdma driver (Vinod)
 - Remove fdma_ prefix for clock names (Arnd)
 - Make _xlate use dma_get_any_channel rather than request_channel (Arnd)
 - Make a common function for _prep_ routines (Vinod)
 - Make driver depend on COMPILE_TEST (Arnd)
 - Remove unnecessary st_fdma_filter_fn (Arnd)
 - Enable FDMA as a module (Arnd)
 - Drop fdma_ clock prefix (Arnd)
 - Fix description as well as example for st, prefix (Arnd)
 - Remove string concatenation from fdma register macros to ease grep'ability (Arnd)
 - Add a XP70 rproc driver for ELF firmware loading and start/stop control (Peter)
 - Add myself as a author of the driver (Peter)

Changes since v2:
 - Change to dma-controller (Arnd)
 - Remove platform data header file and simplifiy code (Arnd)
 - Remove FW_LOADER_USER_HELPER_FALLBACK and rework firmware loading to device config (Vinod)
 - Use SET_RUNTIME_PM_OPS helpers (Vinod)
 - Remove fdma-id dt prop and use compatibles to generate different fdma firmware names (Arnd / Lee)
 - Add sti-asoc-card DT nodes and pinmux config for uniperif player & reader (Peter)
 - Update sti-asoc-card DT binding documentation (Peter)
 - Enable STi audio drivers in multi_v7_defconfig (Peter)

Changes since v1:
 - split into smaller patches for easier / faster review (Vinod)
 - new fill_hw_mode() with common code (Vinod)
 - new config_reqctrl() called from *_prep() instead of device_config cb (Vinod)
 - fdma-xbar support removed (Peter)
 - rework firmware name mechanism so fwname isn't in DT (Peter / Lee)
 - st_fdma_seg_to_mem can be static (Paul)
 - EXPORT_SYMBOL st_fdma_filter_fn not required (Paul)
 - s/channel/channels (vinod)
 - better describe "Must be <3>" (vinod)
 - sizeof(*ehdr) (vinod)
 - print values on error debug (vinod)
 - empty line (Vinod)
 - Update to -EIO (Vinod)
 - Make st_fdma tristate (Paul)
 - Remove __exit tag from .remove (Maxime)
 - Update MAINTAINERS rule to fdma* (Lee)
 - Unit address should match reg property (Lee)

Peter Griffin (18):
  remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
  ARM: multi_v7_defconfig: enable st xp70 rproc driver.
  MAINTAINERS: Add st xp70 rproc driver to STi section.
  dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
    documentation
  dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
  dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
  ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
  MAINTAINERS: Add FDMA driver files to STi section.
  ARM: multi_v7_defconfig: Enable STi FDMA driver
  ASoC: sti: Update DT example to match the driver code
  ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
  ARM: DT: STiH407: Add i2s_out pinctrl configuration
  ARM: DT: STiH407: Add i2s_in pinctrl configuration
  ARM: DT: STiH407: Add spdif_out pinctrl config
  ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
  ARM: STi: DT: STiH407: Add uniperif player dt nodes
  ARM: STi: DT: STiH407: Add uniperif reader dt nodes
  ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card

 Documentation/devicetree/bindings/dma/st_fdma.txt  |  87 ++
 .../devicetree/bindings/sound/st,sti-asoc-card.txt |  20 +-
 MAINTAINERS                                        |   3 +
 arch/arm/boot/dts/stih407-family.dtsi              | 165 ++++
 arch/arm/boot/dts/stih407-pinctrl.dtsi             |  55 ++
 arch/arm/boot/dts/stihxxx-b2120.dtsi               |  40 +
 arch/arm/configs/multi_v7_defconfig                |   5 +
 drivers/dma/Kconfig                                |  12 +
 drivers/dma/Makefile                               |   1 +
 drivers/dma/st_fdma.c                              | 882 +++++++++++++++++++++
 drivers/dma/st_fdma.h                              | 243 ++++++
 drivers/remoteproc/Kconfig                         |   8 +
 drivers/remoteproc/Makefile                        |   1 +
 drivers/remoteproc/st_xp70_rproc.c                 | 380 +++++++++
 include/linux/remoteproc/st_xp70_rproc.h           |  56 ++
 15 files changed, 1948 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
 create mode 100644 drivers/dma/st_fdma.c
 create mode 100644 drivers/dma/st_fdma.h
 create mode 100644 drivers/remoteproc/st_xp70_rproc.c
 create mode 100644 include/linux/remoteproc/st_xp70_rproc.h

-- 
1.9.1

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

* [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
  2016-05-25 16:06 ` Peter Griffin
  (?)
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

XP70 slim core is used as a basis for many IPs in the STi
chipsets such as fdma, display, and demux. To avoid
duplicating the elf loading code in each device driver
an xp70 rproc driver has been created.

This driver is designed to be used by other device drivers
such as fdma, or demux whose IP is based around a xp70 slimcore.
The device driver can call xp70_rproc_alloc() to allocate
an xp70 rproc and xp70_rproc_put() when finished.

This driver takes care of ioremapping the xp70
registers (dmem, imem, slimcore, peripherals), whose offsets
and sizes can change between IP's. It also obtains and enables
any clocks used by the device. This approach avoids having
a double mapping of the registers as xp70_rproc does not register
its own platform device. It also maps well to device tree
abstraction as it allows us to have one dt node for the whole
device.

All of the generic rproc elf loading code can be reused, and
we provide start() stop() hooks to start and stop the xp70
core once the firmware has been loaded. This has been tested
successfully with fdma driver.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/remoteproc/Kconfig               |   8 +
 drivers/remoteproc/Makefile              |   1 +
 drivers/remoteproc/st_xp70_rproc.c       | 380 +++++++++++++++++++++++++++++++
 include/linux/remoteproc/st_xp70_rproc.h |  56 +++++
 4 files changed, 445 insertions(+)
 create mode 100644 drivers/remoteproc/st_xp70_rproc.c
 create mode 100644 include/linux/remoteproc/st_xp70_rproc.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 72e97d7..9e48fd1 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -86,4 +86,12 @@ config ST_REMOTEPROC
 	  processor framework.
 	  This can be either built-in or a loadable module.
 
+config ST_XP70_REMOTEPROC
+	tristate "XP70 slim remoteproc support"
+	depends on ARCH_STI
+	select REMOTEPROC
+	help
+	  Say y here to support xp70 slim core.
+	  If unsure say N.
+
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 279cb2e..b5dab8e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
 obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
+obj-$(CONFIG_ST_XP70_REMOTEPROC)	+= st_xp70_rproc.o
diff --git a/drivers/remoteproc/st_xp70_rproc.c b/drivers/remoteproc/st_xp70_rproc.c
new file mode 100644
index 0000000..6a78e7c
--- /dev/null
+++ b/drivers/remoteproc/st_xp70_rproc.c
@@ -0,0 +1,380 @@
+/*
+ * st_xp70_rproc.c
+ *
+ * Copyright (C) 2016 STMicroelectronics
+ * Author: Peter Griffin <peter.griffin@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/elf.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/remoteproc/st_xp70_rproc.h>
+#include "remoteproc_internal.h"
+
+/* slimcore registers */
+#define XP70_ID_OFST		0x0
+#define XP70_VER_OFST		0x4
+
+#define XP70_EN_OFST		0x8
+#define XP70_EN_RUN			BIT(0)
+
+#define XP70_CLK_GATE_OFST	0xC
+#define XP70_CLK_GATE_DIS		BIT(0)
+#define XP70_CLK_GATE_RESET		BIT(2)
+
+#define XP70_SLIM_PC_OFST	0x20
+
+/* dmem registers */
+#define XP70_REV_ID_OFST	0x0
+#define XP70_REV_ID_MIN_MASK		GENMASK(15, 8)
+#define XP70_REV_ID_MIN(id)		((id & XP70_REV_ID_MIN_MASK) >> 8)
+#define XP70_REV_ID_MAJ_MASK		GENMASK(23, 16)
+#define XP70_REV_ID_MAJ(id)		((id & XP70_REV_ID_MAJ_MASK) >> 16)
+
+
+/* peripherals registers */
+#define XP70_STBUS_SYNC_OFST	0xF88
+#define XP70_STBUS_SYNC_DIS		BIT(0)
+
+#define XP70_INT_SET_OFST	0xFD4
+#define XP70_INT_CLR_OFST	0xFD8
+#define XP70_INT_MASK_OFST	0xFDC
+
+#define XP70_CMD_CLR_OFST	0xFC8
+#define XP70_CMD_MASK_OFST	0xFCC
+
+const char *mem_names[XP70_MEM_MAX] = {
+	[DMEM]		= "dmem",
+	[IMEM]		= "imem",
+};
+
+static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
+{
+	int clk, err = 0;
+
+	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
+		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
+		if (IS_ERR(xp70_rproc->clks[clk])) {
+			err = PTR_ERR(xp70_rproc->clks[clk]);
+			if (err == -EPROBE_DEFER)
+				goto err_put_clks;
+			xp70_rproc->clks[clk] = NULL;
+			break;
+		}
+	}
+
+	return 0;
+
+err_put_clks:
+	while (--clk >= 0)
+		clk_put(xp70_rproc->clks[clk]);
+
+	return err;
+}
+
+static void xp70_clk_disable(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk;
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
+		clk_disable_unprepare(xp70_rproc->clks[clk]);
+}
+
+static int xp70_clk_enable(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk, ret;
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++) {
+		ret = clk_prepare_enable(xp70_rproc->clks[clk]);
+		if (ret)
+			goto err_disable_clks;
+	}
+
+	return 0;
+
+err_disable_clks:
+	while (--clk >= 0)
+		clk_disable_unprepare(xp70_rproc->clks[clk]);
+
+	return ret;
+}
+
+/**
+ * Remoteproc xp70 specific device handlers
+ */
+static int xp70_rproc_start(struct rproc *rproc)
+{
+	struct device *dev = &rproc->dev;
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	unsigned long hw_id, hw_ver, fw_rev;
+	u32 val, ret = 0;
+
+	ret = xp70_clk_enable(xp70_rproc);
+	if (ret) {
+		dev_err(dev, "Failed to enable clocks\n");
+		goto err_clk;
+	}
+
+	/* disable CPU pipeline clock & reset cpu pipeline */
+	val = XP70_CLK_GATE_DIS | XP70_CLK_GATE_RESET;
+	writel_relaxed(val, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	/* disable SLIM core STBus sync */
+	writel_relaxed(XP70_STBUS_SYNC_DIS,
+		xp70_rproc->peri + XP70_STBUS_SYNC_OFST);
+
+	/* enable cpu pipeline clock */
+	writel_relaxed(!XP70_CLK_GATE_DIS,
+		xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	/* clear int & cmd mailbox */
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_CLR_OFST);
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_CLR_OFST);
+
+	/* enable all channels cmd & int */
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
+
+	/* enable cpu */
+	writel(XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
+
+	hw_id = readl_relaxed(xp70_rproc->slimcore + XP70_ID_OFST);
+	hw_ver = readl_relaxed(xp70_rproc->slimcore + XP70_VER_OFST);
+
+	fw_rev = readl_relaxed(xp70_rproc->mem[DMEM].cpu_addr +
+			XP70_REV_ID_OFST);
+
+	dev_info(dev, "fw rev:%ld.%ld on SLIM %ld.%ld\n",
+		 XP70_REV_ID_MAJ(fw_rev), XP70_REV_ID_MIN(fw_rev),
+		 hw_id, hw_ver);
+
+	dev_dbg(dev, "XP70 started\n");
+
+err_clk:
+	return ret;
+}
+
+static int xp70_rproc_stop(struct rproc *rproc)
+{
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	u32 val;
+
+	/* mask all (cmd & int) channels */
+	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
+	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
+
+	/* disable cpu pipeline clock */
+	writel_relaxed(XP70_CLK_GATE_DIS
+		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
+
+	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
+	if (val & XP70_EN_RUN)
+		dev_warn(&rproc->dev, "Failed to disable XP70");
+
+	xp70_clk_disable(xp70_rproc);
+
+	dev_dbg(&rproc->dev, "xp70 stopped\n");
+
+	return 0;
+}
+
+static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	void *va = NULL;
+	int i;
+
+	for (i = 0; i < XP70_MEM_MAX; i++) {
+
+		if (da != xp70_rproc->mem[i].bus_addr)
+			continue;
+
+		va = xp70_rproc->mem[i].cpu_addr;
+			break;
+	}
+
+	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
+		, __func__, da, len, va);
+
+	return va;
+}
+
+static struct rproc_ops xp70_rproc_ops = {
+	.start		= xp70_rproc_start,
+	.stop		= xp70_rproc_stop,
+	.da_to_va       = xp70_rproc_da_to_va,
+};
+
+/**
+ * Firmware handler operations: sanity, boot address, load ...
+ */
+
+static struct resource_table empty_rsc_tbl = {
+	.ver = 1,
+	.num = 0,
+};
+
+static struct resource_table *xp70_rproc_find_rsc_table(struct rproc *rproc,
+					       const struct firmware *fw,
+					       int *tablesz)
+{
+	if (!fw)
+		return NULL;
+
+	*tablesz = sizeof(empty_rsc_tbl);
+	return &empty_rsc_tbl;
+}
+
+static struct resource_table *xp70_rproc_find_loaded_rsc_table(struct rproc *rproc,
+						      const struct firmware *fw)
+{
+	if (!fw)
+		return NULL;
+
+	return &empty_rsc_tbl;
+}
+
+static struct rproc_fw_ops xp70_rproc_fw_ops = {
+	.find_rsc_table = xp70_rproc_find_rsc_table,
+	.find_loaded_rsc_table = xp70_rproc_find_loaded_rsc_table,
+};
+
+/**
+  * xp70_rproc_alloc - allocate and initialise xp70 rproc
+  * @pdev: Pointer to the platform_device struct
+  * @fw_name: Name of firmware for rproc to use
+  *
+  * Function for allocating and initialising a xp70 rproc for use by
+  * device drivers whose IP is based around the xp70 slim core. It
+  * obtains and enables any clocks required by the xp70 core and also
+  * ioremaps the various IO.
+  *
+  * Returns rproc pointer or PTR_ERR() on error.
+  */
+
+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
+{
+	struct device *dev = &pdev->dev;
+	struct st_xp70_rproc *xp70_rproc;
+	struct device_node *np = dev->of_node;
+	struct rproc *rproc;
+	struct resource *res;
+	int err, i;
+	const struct rproc_fw_ops *elf_ops;
+
+	if (!np || !fw_name)
+		return ERR_PTR(-EINVAL);
+
+	if (!of_device_is_compatible(np, "st,xp70-rproc"))
+		return ERR_PTR(-EINVAL);
+
+	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
+			fw_name, sizeof(*xp70_rproc));
+	if (!rproc)
+		return ERR_PTR(-ENOMEM);
+
+	rproc->has_iommu = false;
+
+	xp70_rproc = rproc->priv;
+	xp70_rproc->rproc = rproc;
+
+	/* Get standard ELF ops */
+	elf_ops = rproc_get_elf_ops();
+
+	/* Use some generic elf ops */
+	xp70_rproc_fw_ops.load = elf_ops->load;
+	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
+
+	rproc->fw_ops = &xp70_rproc_fw_ops;
+
+	/* get imem and dmem */
+	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
+		res = xp70_rproc->mem[i].io_res;
+
+		res = platform_get_resource_byname
+			(pdev, IORESOURCE_MEM, mem_names[i]);
+
+		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
+		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
+			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
+			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
+			goto err;
+		}
+		xp70_rproc->mem[i].bus_addr = res->start;
+		xp70_rproc->mem[i].size = resource_size(res);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
+
+	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
+	if (IS_ERR(xp70_rproc->slimcore)) {
+		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
+		err = PTR_ERR(xp70_rproc->slimcore);
+		goto err;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
+
+	xp70_rproc->peri = devm_ioremap_resource(dev, res);
+	if (IS_ERR(xp70_rproc->peri)) {
+		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
+		err = PTR_ERR(xp70_rproc->peri);
+		goto err;
+	}
+
+	err = xp70_clk_get(xp70_rproc, dev);
+	if (err)
+		goto err;
+
+	/* Register as a remoteproc device */
+	err = rproc_add(rproc);
+	if (err) {
+		dev_err(dev, "registration of xp70 remoteproc failed\n");
+		goto err;
+	}
+
+	dev_dbg(dev, "XP70 rproc init successful\n");
+	return rproc;
+
+err:
+	rproc_put(rproc);
+	return ERR_PTR(err);
+}
+EXPORT_SYMBOL(xp70_rproc_alloc);
+
+/**
+  * xp70_rproc_put - put xp70 rproc resources
+  * @xp70_rproc: Pointer to the st_xp70_rproc struct
+  *
+  * Function for calling respective _put() functions on
+  * xp70_rproc resources.
+  *
+  * Returns rproc pointer or PTR_ERR() on error.
+  */
+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk;
+
+	if (!xp70_rproc)
+		return;
+
+	rproc_put(xp70_rproc->rproc);
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
+		clk_put(xp70_rproc->clks[clk]);
+
+}
+EXPORT_SYMBOL(xp70_rproc_put);
+
+MODULE_AUTHOR("Peter Griffin");
+MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
new file mode 100644
index 0000000..3aba2de
--- /dev/null
+++ b/include/linux/remoteproc/st_xp70_rproc.h
@@ -0,0 +1,56 @@
+/*
+ * st_xp70_rproc.h
+ *
+ * Copyright (C) 2016 STMicroelectronics
+ * Author: Peter Griffin <peter.griffin@linaro.org>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef _ST_XP70_H
+#define _ST_XP70_H
+
+#define XP70_MEM_MAX 2
+#define XP70_MAX_CLK 4
+#define NAME_SZ 10
+
+enum {
+	DMEM,
+	IMEM,
+};
+
+/**
+ * struct xp70_mem - xp70 internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address from Wakeup M3 view
+ * @size: Size of the memory region
+ */
+struct xp70_mem {
+	void __iomem *cpu_addr;
+	phys_addr_t bus_addr;
+	u32 dev_addr;
+	size_t size;
+	struct resource *io_res;
+};
+
+/**
+ * struct st_xp70_rproc - XP70 slim core
+ * @rproc: rproc handle
+ * @pdev: pointer to platform device
+ * @mem: xp70 memory information
+ * @slimcore: xp70 slimcore regs
+ * @peri: xp70 peripheral regs
+ * @clks: xp70 clocks
+ */
+struct st_xp70_rproc {
+	struct rproc *rproc;
+	struct platform_device *pdev;
+	struct xp70_mem mem[XP70_MEM_MAX];
+	void __iomem *slimcore;
+	void __iomem *peri;
+	struct clk *clks[XP70_MAX_CLK];
+};
+
+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
+
+#endif
-- 
1.9.1

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

* [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, devicetree, linux-remoteproc, lee.jones, dmaengine

XP70 slim core is used as a basis for many IPs in the STi
chipsets such as fdma, display, and demux. To avoid
duplicating the elf loading code in each device driver
an xp70 rproc driver has been created.

This driver is designed to be used by other device drivers
such as fdma, or demux whose IP is based around a xp70 slimcore.
The device driver can call xp70_rproc_alloc() to allocate
an xp70 rproc and xp70_rproc_put() when finished.

This driver takes care of ioremapping the xp70
registers (dmem, imem, slimcore, peripherals), whose offsets
and sizes can change between IP's. It also obtains and enables
any clocks used by the device. This approach avoids having
a double mapping of the registers as xp70_rproc does not register
its own platform device. It also maps well to device tree
abstraction as it allows us to have one dt node for the whole
device.

All of the generic rproc elf loading code can be reused, and
we provide start() stop() hooks to start and stop the xp70
core once the firmware has been loaded. This has been tested
successfully with fdma driver.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/remoteproc/Kconfig               |   8 +
 drivers/remoteproc/Makefile              |   1 +
 drivers/remoteproc/st_xp70_rproc.c       | 380 +++++++++++++++++++++++++++++++
 include/linux/remoteproc/st_xp70_rproc.h |  56 +++++
 4 files changed, 445 insertions(+)
 create mode 100644 drivers/remoteproc/st_xp70_rproc.c
 create mode 100644 include/linux/remoteproc/st_xp70_rproc.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 72e97d7..9e48fd1 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -86,4 +86,12 @@ config ST_REMOTEPROC
 	  processor framework.
 	  This can be either built-in or a loadable module.
 
+config ST_XP70_REMOTEPROC
+	tristate "XP70 slim remoteproc support"
+	depends on ARCH_STI
+	select REMOTEPROC
+	help
+	  Say y here to support xp70 slim core.
+	  If unsure say N.
+
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 279cb2e..b5dab8e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
 obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
+obj-$(CONFIG_ST_XP70_REMOTEPROC)	+= st_xp70_rproc.o
diff --git a/drivers/remoteproc/st_xp70_rproc.c b/drivers/remoteproc/st_xp70_rproc.c
new file mode 100644
index 0000000..6a78e7c
--- /dev/null
+++ b/drivers/remoteproc/st_xp70_rproc.c
@@ -0,0 +1,380 @@
+/*
+ * st_xp70_rproc.c
+ *
+ * Copyright (C) 2016 STMicroelectronics
+ * Author: Peter Griffin <peter.griffin@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/elf.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/remoteproc/st_xp70_rproc.h>
+#include "remoteproc_internal.h"
+
+/* slimcore registers */
+#define XP70_ID_OFST		0x0
+#define XP70_VER_OFST		0x4
+
+#define XP70_EN_OFST		0x8
+#define XP70_EN_RUN			BIT(0)
+
+#define XP70_CLK_GATE_OFST	0xC
+#define XP70_CLK_GATE_DIS		BIT(0)
+#define XP70_CLK_GATE_RESET		BIT(2)
+
+#define XP70_SLIM_PC_OFST	0x20
+
+/* dmem registers */
+#define XP70_REV_ID_OFST	0x0
+#define XP70_REV_ID_MIN_MASK		GENMASK(15, 8)
+#define XP70_REV_ID_MIN(id)		((id & XP70_REV_ID_MIN_MASK) >> 8)
+#define XP70_REV_ID_MAJ_MASK		GENMASK(23, 16)
+#define XP70_REV_ID_MAJ(id)		((id & XP70_REV_ID_MAJ_MASK) >> 16)
+
+
+/* peripherals registers */
+#define XP70_STBUS_SYNC_OFST	0xF88
+#define XP70_STBUS_SYNC_DIS		BIT(0)
+
+#define XP70_INT_SET_OFST	0xFD4
+#define XP70_INT_CLR_OFST	0xFD8
+#define XP70_INT_MASK_OFST	0xFDC
+
+#define XP70_CMD_CLR_OFST	0xFC8
+#define XP70_CMD_MASK_OFST	0xFCC
+
+const char *mem_names[XP70_MEM_MAX] = {
+	[DMEM]		= "dmem",
+	[IMEM]		= "imem",
+};
+
+static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
+{
+	int clk, err = 0;
+
+	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
+		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
+		if (IS_ERR(xp70_rproc->clks[clk])) {
+			err = PTR_ERR(xp70_rproc->clks[clk]);
+			if (err == -EPROBE_DEFER)
+				goto err_put_clks;
+			xp70_rproc->clks[clk] = NULL;
+			break;
+		}
+	}
+
+	return 0;
+
+err_put_clks:
+	while (--clk >= 0)
+		clk_put(xp70_rproc->clks[clk]);
+
+	return err;
+}
+
+static void xp70_clk_disable(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk;
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
+		clk_disable_unprepare(xp70_rproc->clks[clk]);
+}
+
+static int xp70_clk_enable(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk, ret;
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++) {
+		ret = clk_prepare_enable(xp70_rproc->clks[clk]);
+		if (ret)
+			goto err_disable_clks;
+	}
+
+	return 0;
+
+err_disable_clks:
+	while (--clk >= 0)
+		clk_disable_unprepare(xp70_rproc->clks[clk]);
+
+	return ret;
+}
+
+/**
+ * Remoteproc xp70 specific device handlers
+ */
+static int xp70_rproc_start(struct rproc *rproc)
+{
+	struct device *dev = &rproc->dev;
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	unsigned long hw_id, hw_ver, fw_rev;
+	u32 val, ret = 0;
+
+	ret = xp70_clk_enable(xp70_rproc);
+	if (ret) {
+		dev_err(dev, "Failed to enable clocks\n");
+		goto err_clk;
+	}
+
+	/* disable CPU pipeline clock & reset cpu pipeline */
+	val = XP70_CLK_GATE_DIS | XP70_CLK_GATE_RESET;
+	writel_relaxed(val, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	/* disable SLIM core STBus sync */
+	writel_relaxed(XP70_STBUS_SYNC_DIS,
+		xp70_rproc->peri + XP70_STBUS_SYNC_OFST);
+
+	/* enable cpu pipeline clock */
+	writel_relaxed(!XP70_CLK_GATE_DIS,
+		xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	/* clear int & cmd mailbox */
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_CLR_OFST);
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_CLR_OFST);
+
+	/* enable all channels cmd & int */
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
+
+	/* enable cpu */
+	writel(XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
+
+	hw_id = readl_relaxed(xp70_rproc->slimcore + XP70_ID_OFST);
+	hw_ver = readl_relaxed(xp70_rproc->slimcore + XP70_VER_OFST);
+
+	fw_rev = readl_relaxed(xp70_rproc->mem[DMEM].cpu_addr +
+			XP70_REV_ID_OFST);
+
+	dev_info(dev, "fw rev:%ld.%ld on SLIM %ld.%ld\n",
+		 XP70_REV_ID_MAJ(fw_rev), XP70_REV_ID_MIN(fw_rev),
+		 hw_id, hw_ver);
+
+	dev_dbg(dev, "XP70 started\n");
+
+err_clk:
+	return ret;
+}
+
+static int xp70_rproc_stop(struct rproc *rproc)
+{
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	u32 val;
+
+	/* mask all (cmd & int) channels */
+	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
+	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
+
+	/* disable cpu pipeline clock */
+	writel_relaxed(XP70_CLK_GATE_DIS
+		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
+
+	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
+	if (val & XP70_EN_RUN)
+		dev_warn(&rproc->dev, "Failed to disable XP70");
+
+	xp70_clk_disable(xp70_rproc);
+
+	dev_dbg(&rproc->dev, "xp70 stopped\n");
+
+	return 0;
+}
+
+static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	void *va = NULL;
+	int i;
+
+	for (i = 0; i < XP70_MEM_MAX; i++) {
+
+		if (da != xp70_rproc->mem[i].bus_addr)
+			continue;
+
+		va = xp70_rproc->mem[i].cpu_addr;
+			break;
+	}
+
+	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
+		, __func__, da, len, va);
+
+	return va;
+}
+
+static struct rproc_ops xp70_rproc_ops = {
+	.start		= xp70_rproc_start,
+	.stop		= xp70_rproc_stop,
+	.da_to_va       = xp70_rproc_da_to_va,
+};
+
+/**
+ * Firmware handler operations: sanity, boot address, load ...
+ */
+
+static struct resource_table empty_rsc_tbl = {
+	.ver = 1,
+	.num = 0,
+};
+
+static struct resource_table *xp70_rproc_find_rsc_table(struct rproc *rproc,
+					       const struct firmware *fw,
+					       int *tablesz)
+{
+	if (!fw)
+		return NULL;
+
+	*tablesz = sizeof(empty_rsc_tbl);
+	return &empty_rsc_tbl;
+}
+
+static struct resource_table *xp70_rproc_find_loaded_rsc_table(struct rproc *rproc,
+						      const struct firmware *fw)
+{
+	if (!fw)
+		return NULL;
+
+	return &empty_rsc_tbl;
+}
+
+static struct rproc_fw_ops xp70_rproc_fw_ops = {
+	.find_rsc_table = xp70_rproc_find_rsc_table,
+	.find_loaded_rsc_table = xp70_rproc_find_loaded_rsc_table,
+};
+
+/**
+  * xp70_rproc_alloc - allocate and initialise xp70 rproc
+  * @pdev: Pointer to the platform_device struct
+  * @fw_name: Name of firmware for rproc to use
+  *
+  * Function for allocating and initialising a xp70 rproc for use by
+  * device drivers whose IP is based around the xp70 slim core. It
+  * obtains and enables any clocks required by the xp70 core and also
+  * ioremaps the various IO.
+  *
+  * Returns rproc pointer or PTR_ERR() on error.
+  */
+
+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
+{
+	struct device *dev = &pdev->dev;
+	struct st_xp70_rproc *xp70_rproc;
+	struct device_node *np = dev->of_node;
+	struct rproc *rproc;
+	struct resource *res;
+	int err, i;
+	const struct rproc_fw_ops *elf_ops;
+
+	if (!np || !fw_name)
+		return ERR_PTR(-EINVAL);
+
+	if (!of_device_is_compatible(np, "st,xp70-rproc"))
+		return ERR_PTR(-EINVAL);
+
+	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
+			fw_name, sizeof(*xp70_rproc));
+	if (!rproc)
+		return ERR_PTR(-ENOMEM);
+
+	rproc->has_iommu = false;
+
+	xp70_rproc = rproc->priv;
+	xp70_rproc->rproc = rproc;
+
+	/* Get standard ELF ops */
+	elf_ops = rproc_get_elf_ops();
+
+	/* Use some generic elf ops */
+	xp70_rproc_fw_ops.load = elf_ops->load;
+	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
+
+	rproc->fw_ops = &xp70_rproc_fw_ops;
+
+	/* get imem and dmem */
+	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
+		res = xp70_rproc->mem[i].io_res;
+
+		res = platform_get_resource_byname
+			(pdev, IORESOURCE_MEM, mem_names[i]);
+
+		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
+		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
+			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
+			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
+			goto err;
+		}
+		xp70_rproc->mem[i].bus_addr = res->start;
+		xp70_rproc->mem[i].size = resource_size(res);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
+
+	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
+	if (IS_ERR(xp70_rproc->slimcore)) {
+		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
+		err = PTR_ERR(xp70_rproc->slimcore);
+		goto err;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
+
+	xp70_rproc->peri = devm_ioremap_resource(dev, res);
+	if (IS_ERR(xp70_rproc->peri)) {
+		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
+		err = PTR_ERR(xp70_rproc->peri);
+		goto err;
+	}
+
+	err = xp70_clk_get(xp70_rproc, dev);
+	if (err)
+		goto err;
+
+	/* Register as a remoteproc device */
+	err = rproc_add(rproc);
+	if (err) {
+		dev_err(dev, "registration of xp70 remoteproc failed\n");
+		goto err;
+	}
+
+	dev_dbg(dev, "XP70 rproc init successful\n");
+	return rproc;
+
+err:
+	rproc_put(rproc);
+	return ERR_PTR(err);
+}
+EXPORT_SYMBOL(xp70_rproc_alloc);
+
+/**
+  * xp70_rproc_put - put xp70 rproc resources
+  * @xp70_rproc: Pointer to the st_xp70_rproc struct
+  *
+  * Function for calling respective _put() functions on
+  * xp70_rproc resources.
+  *
+  * Returns rproc pointer or PTR_ERR() on error.
+  */
+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk;
+
+	if (!xp70_rproc)
+		return;
+
+	rproc_put(xp70_rproc->rproc);
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
+		clk_put(xp70_rproc->clks[clk]);
+
+}
+EXPORT_SYMBOL(xp70_rproc_put);
+
+MODULE_AUTHOR("Peter Griffin");
+MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
new file mode 100644
index 0000000..3aba2de
--- /dev/null
+++ b/include/linux/remoteproc/st_xp70_rproc.h
@@ -0,0 +1,56 @@
+/*
+ * st_xp70_rproc.h
+ *
+ * Copyright (C) 2016 STMicroelectronics
+ * Author: Peter Griffin <peter.griffin@linaro.org>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef _ST_XP70_H
+#define _ST_XP70_H
+
+#define XP70_MEM_MAX 2
+#define XP70_MAX_CLK 4
+#define NAME_SZ 10
+
+enum {
+	DMEM,
+	IMEM,
+};
+
+/**
+ * struct xp70_mem - xp70 internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address from Wakeup M3 view
+ * @size: Size of the memory region
+ */
+struct xp70_mem {
+	void __iomem *cpu_addr;
+	phys_addr_t bus_addr;
+	u32 dev_addr;
+	size_t size;
+	struct resource *io_res;
+};
+
+/**
+ * struct st_xp70_rproc - XP70 slim core
+ * @rproc: rproc handle
+ * @pdev: pointer to platform device
+ * @mem: xp70 memory information
+ * @slimcore: xp70 slimcore regs
+ * @peri: xp70 peripheral regs
+ * @clks: xp70 clocks
+ */
+struct st_xp70_rproc {
+	struct rproc *rproc;
+	struct platform_device *pdev;
+	struct xp70_mem mem[XP70_MEM_MAX];
+	void __iomem *slimcore;
+	void __iomem *peri;
+	struct clk *clks[XP70_MAX_CLK];
+};
+
+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
+
+#endif
-- 
1.9.1

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

* [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

XP70 slim core is used as a basis for many IPs in the STi
chipsets such as fdma, display, and demux. To avoid
duplicating the elf loading code in each device driver
an xp70 rproc driver has been created.

This driver is designed to be used by other device drivers
such as fdma, or demux whose IP is based around a xp70 slimcore.
The device driver can call xp70_rproc_alloc() to allocate
an xp70 rproc and xp70_rproc_put() when finished.

This driver takes care of ioremapping the xp70
registers (dmem, imem, slimcore, peripherals), whose offsets
and sizes can change between IP's. It also obtains and enables
any clocks used by the device. This approach avoids having
a double mapping of the registers as xp70_rproc does not register
its own platform device. It also maps well to device tree
abstraction as it allows us to have one dt node for the whole
device.

All of the generic rproc elf loading code can be reused, and
we provide start() stop() hooks to start and stop the xp70
core once the firmware has been loaded. This has been tested
successfully with fdma driver.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/remoteproc/Kconfig               |   8 +
 drivers/remoteproc/Makefile              |   1 +
 drivers/remoteproc/st_xp70_rproc.c       | 380 +++++++++++++++++++++++++++++++
 include/linux/remoteproc/st_xp70_rproc.h |  56 +++++
 4 files changed, 445 insertions(+)
 create mode 100644 drivers/remoteproc/st_xp70_rproc.c
 create mode 100644 include/linux/remoteproc/st_xp70_rproc.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 72e97d7..9e48fd1 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -86,4 +86,12 @@ config ST_REMOTEPROC
 	  processor framework.
 	  This can be either built-in or a loadable module.
 
+config ST_XP70_REMOTEPROC
+	tristate "XP70 slim remoteproc support"
+	depends on ARCH_STI
+	select REMOTEPROC
+	help
+	  Say y here to support xp70 slim core.
+	  If unsure say N.
+
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 279cb2e..b5dab8e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
 obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
+obj-$(CONFIG_ST_XP70_REMOTEPROC)	+= st_xp70_rproc.o
diff --git a/drivers/remoteproc/st_xp70_rproc.c b/drivers/remoteproc/st_xp70_rproc.c
new file mode 100644
index 0000000..6a78e7c
--- /dev/null
+++ b/drivers/remoteproc/st_xp70_rproc.c
@@ -0,0 +1,380 @@
+/*
+ * st_xp70_rproc.c
+ *
+ * Copyright (C) 2016 STMicroelectronics
+ * Author: Peter Griffin <peter.griffin@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/elf.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/remoteproc/st_xp70_rproc.h>
+#include "remoteproc_internal.h"
+
+/* slimcore registers */
+#define XP70_ID_OFST		0x0
+#define XP70_VER_OFST		0x4
+
+#define XP70_EN_OFST		0x8
+#define XP70_EN_RUN			BIT(0)
+
+#define XP70_CLK_GATE_OFST	0xC
+#define XP70_CLK_GATE_DIS		BIT(0)
+#define XP70_CLK_GATE_RESET		BIT(2)
+
+#define XP70_SLIM_PC_OFST	0x20
+
+/* dmem registers */
+#define XP70_REV_ID_OFST	0x0
+#define XP70_REV_ID_MIN_MASK		GENMASK(15, 8)
+#define XP70_REV_ID_MIN(id)		((id & XP70_REV_ID_MIN_MASK) >> 8)
+#define XP70_REV_ID_MAJ_MASK		GENMASK(23, 16)
+#define XP70_REV_ID_MAJ(id)		((id & XP70_REV_ID_MAJ_MASK) >> 16)
+
+
+/* peripherals registers */
+#define XP70_STBUS_SYNC_OFST	0xF88
+#define XP70_STBUS_SYNC_DIS		BIT(0)
+
+#define XP70_INT_SET_OFST	0xFD4
+#define XP70_INT_CLR_OFST	0xFD8
+#define XP70_INT_MASK_OFST	0xFDC
+
+#define XP70_CMD_CLR_OFST	0xFC8
+#define XP70_CMD_MASK_OFST	0xFCC
+
+const char *mem_names[XP70_MEM_MAX] = {
+	[DMEM]		= "dmem",
+	[IMEM]		= "imem",
+};
+
+static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
+{
+	int clk, err = 0;
+
+	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
+		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
+		if (IS_ERR(xp70_rproc->clks[clk])) {
+			err = PTR_ERR(xp70_rproc->clks[clk]);
+			if (err == -EPROBE_DEFER)
+				goto err_put_clks;
+			xp70_rproc->clks[clk] = NULL;
+			break;
+		}
+	}
+
+	return 0;
+
+err_put_clks:
+	while (--clk >= 0)
+		clk_put(xp70_rproc->clks[clk]);
+
+	return err;
+}
+
+static void xp70_clk_disable(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk;
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
+		clk_disable_unprepare(xp70_rproc->clks[clk]);
+}
+
+static int xp70_clk_enable(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk, ret;
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++) {
+		ret = clk_prepare_enable(xp70_rproc->clks[clk]);
+		if (ret)
+			goto err_disable_clks;
+	}
+
+	return 0;
+
+err_disable_clks:
+	while (--clk >= 0)
+		clk_disable_unprepare(xp70_rproc->clks[clk]);
+
+	return ret;
+}
+
+/**
+ * Remoteproc xp70 specific device handlers
+ */
+static int xp70_rproc_start(struct rproc *rproc)
+{
+	struct device *dev = &rproc->dev;
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	unsigned long hw_id, hw_ver, fw_rev;
+	u32 val, ret = 0;
+
+	ret = xp70_clk_enable(xp70_rproc);
+	if (ret) {
+		dev_err(dev, "Failed to enable clocks\n");
+		goto err_clk;
+	}
+
+	/* disable CPU pipeline clock & reset cpu pipeline */
+	val = XP70_CLK_GATE_DIS | XP70_CLK_GATE_RESET;
+	writel_relaxed(val, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	/* disable SLIM core STBus sync */
+	writel_relaxed(XP70_STBUS_SYNC_DIS,
+		xp70_rproc->peri + XP70_STBUS_SYNC_OFST);
+
+	/* enable cpu pipeline clock */
+	writel_relaxed(!XP70_CLK_GATE_DIS,
+		xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	/* clear int & cmd mailbox */
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_CLR_OFST);
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_CLR_OFST);
+
+	/* enable all channels cmd & int */
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
+	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
+
+	/* enable cpu */
+	writel(XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
+
+	hw_id = readl_relaxed(xp70_rproc->slimcore + XP70_ID_OFST);
+	hw_ver = readl_relaxed(xp70_rproc->slimcore + XP70_VER_OFST);
+
+	fw_rev = readl_relaxed(xp70_rproc->mem[DMEM].cpu_addr +
+			XP70_REV_ID_OFST);
+
+	dev_info(dev, "fw rev:%ld.%ld on SLIM %ld.%ld\n",
+		 XP70_REV_ID_MAJ(fw_rev), XP70_REV_ID_MIN(fw_rev),
+		 hw_id, hw_ver);
+
+	dev_dbg(dev, "XP70 started\n");
+
+err_clk:
+	return ret;
+}
+
+static int xp70_rproc_stop(struct rproc *rproc)
+{
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	u32 val;
+
+	/* mask all (cmd & int) channels */
+	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
+	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
+
+	/* disable cpu pipeline clock */
+	writel_relaxed(XP70_CLK_GATE_DIS
+		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
+
+	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
+
+	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
+	if (val & XP70_EN_RUN)
+		dev_warn(&rproc->dev, "Failed to disable XP70");
+
+	xp70_clk_disable(xp70_rproc);
+
+	dev_dbg(&rproc->dev, "xp70 stopped\n");
+
+	return 0;
+}
+
+static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+	struct st_xp70_rproc *xp70_rproc = rproc->priv;
+	void *va = NULL;
+	int i;
+
+	for (i = 0; i < XP70_MEM_MAX; i++) {
+
+		if (da != xp70_rproc->mem[i].bus_addr)
+			continue;
+
+		va = xp70_rproc->mem[i].cpu_addr;
+			break;
+	}
+
+	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
+		, __func__, da, len, va);
+
+	return va;
+}
+
+static struct rproc_ops xp70_rproc_ops = {
+	.start		= xp70_rproc_start,
+	.stop		= xp70_rproc_stop,
+	.da_to_va       = xp70_rproc_da_to_va,
+};
+
+/**
+ * Firmware handler operations: sanity, boot address, load ...
+ */
+
+static struct resource_table empty_rsc_tbl = {
+	.ver = 1,
+	.num = 0,
+};
+
+static struct resource_table *xp70_rproc_find_rsc_table(struct rproc *rproc,
+					       const struct firmware *fw,
+					       int *tablesz)
+{
+	if (!fw)
+		return NULL;
+
+	*tablesz = sizeof(empty_rsc_tbl);
+	return &empty_rsc_tbl;
+}
+
+static struct resource_table *xp70_rproc_find_loaded_rsc_table(struct rproc *rproc,
+						      const struct firmware *fw)
+{
+	if (!fw)
+		return NULL;
+
+	return &empty_rsc_tbl;
+}
+
+static struct rproc_fw_ops xp70_rproc_fw_ops = {
+	.find_rsc_table = xp70_rproc_find_rsc_table,
+	.find_loaded_rsc_table = xp70_rproc_find_loaded_rsc_table,
+};
+
+/**
+  * xp70_rproc_alloc - allocate and initialise xp70 rproc
+  * @pdev: Pointer to the platform_device struct
+  * @fw_name: Name of firmware for rproc to use
+  *
+  * Function for allocating and initialising a xp70 rproc for use by
+  * device drivers whose IP is based around the xp70 slim core. It
+  * obtains and enables any clocks required by the xp70 core and also
+  * ioremaps the various IO.
+  *
+  * Returns rproc pointer or PTR_ERR() on error.
+  */
+
+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
+{
+	struct device *dev = &pdev->dev;
+	struct st_xp70_rproc *xp70_rproc;
+	struct device_node *np = dev->of_node;
+	struct rproc *rproc;
+	struct resource *res;
+	int err, i;
+	const struct rproc_fw_ops *elf_ops;
+
+	if (!np || !fw_name)
+		return ERR_PTR(-EINVAL);
+
+	if (!of_device_is_compatible(np, "st,xp70-rproc"))
+		return ERR_PTR(-EINVAL);
+
+	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
+			fw_name, sizeof(*xp70_rproc));
+	if (!rproc)
+		return ERR_PTR(-ENOMEM);
+
+	rproc->has_iommu = false;
+
+	xp70_rproc = rproc->priv;
+	xp70_rproc->rproc = rproc;
+
+	/* Get standard ELF ops */
+	elf_ops = rproc_get_elf_ops();
+
+	/* Use some generic elf ops */
+	xp70_rproc_fw_ops.load = elf_ops->load;
+	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
+
+	rproc->fw_ops = &xp70_rproc_fw_ops;
+
+	/* get imem and dmem */
+	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
+		res = xp70_rproc->mem[i].io_res;
+
+		res = platform_get_resource_byname
+			(pdev, IORESOURCE_MEM, mem_names[i]);
+
+		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
+		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
+			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
+			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
+			goto err;
+		}
+		xp70_rproc->mem[i].bus_addr = res->start;
+		xp70_rproc->mem[i].size = resource_size(res);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
+
+	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
+	if (IS_ERR(xp70_rproc->slimcore)) {
+		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
+		err = PTR_ERR(xp70_rproc->slimcore);
+		goto err;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
+
+	xp70_rproc->peri = devm_ioremap_resource(dev, res);
+	if (IS_ERR(xp70_rproc->peri)) {
+		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
+		err = PTR_ERR(xp70_rproc->peri);
+		goto err;
+	}
+
+	err = xp70_clk_get(xp70_rproc, dev);
+	if (err)
+		goto err;
+
+	/* Register as a remoteproc device */
+	err = rproc_add(rproc);
+	if (err) {
+		dev_err(dev, "registration of xp70 remoteproc failed\n");
+		goto err;
+	}
+
+	dev_dbg(dev, "XP70 rproc init successful\n");
+	return rproc;
+
+err:
+	rproc_put(rproc);
+	return ERR_PTR(err);
+}
+EXPORT_SYMBOL(xp70_rproc_alloc);
+
+/**
+  * xp70_rproc_put - put xp70 rproc resources
+  * @xp70_rproc: Pointer to the st_xp70_rproc struct
+  *
+  * Function for calling respective _put() functions on
+  * xp70_rproc resources.
+  *
+  * Returns rproc pointer or PTR_ERR() on error.
+  */
+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
+{
+	int clk;
+
+	if (!xp70_rproc)
+		return;
+
+	rproc_put(xp70_rproc->rproc);
+
+	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
+		clk_put(xp70_rproc->clks[clk]);
+
+}
+EXPORT_SYMBOL(xp70_rproc_put);
+
+MODULE_AUTHOR("Peter Griffin");
+MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
new file mode 100644
index 0000000..3aba2de
--- /dev/null
+++ b/include/linux/remoteproc/st_xp70_rproc.h
@@ -0,0 +1,56 @@
+/*
+ * st_xp70_rproc.h
+ *
+ * Copyright (C) 2016 STMicroelectronics
+ * Author: Peter Griffin <peter.griffin@linaro.org>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef _ST_XP70_H
+#define _ST_XP70_H
+
+#define XP70_MEM_MAX 2
+#define XP70_MAX_CLK 4
+#define NAME_SZ 10
+
+enum {
+	DMEM,
+	IMEM,
+};
+
+/**
+ * struct xp70_mem - xp70 internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address from Wakeup M3 view
+ * @size: Size of the memory region
+ */
+struct xp70_mem {
+	void __iomem *cpu_addr;
+	phys_addr_t bus_addr;
+	u32 dev_addr;
+	size_t size;
+	struct resource *io_res;
+};
+
+/**
+ * struct st_xp70_rproc - XP70 slim core
+ * @rproc: rproc handle
+ * @pdev: pointer to platform device
+ * @mem: xp70 memory information
+ * @slimcore: xp70 slimcore regs
+ * @peri: xp70 peripheral regs
+ * @clks: xp70 clocks
+ */
+struct st_xp70_rproc {
+	struct rproc *rproc;
+	struct platform_device *pdev;
+	struct xp70_mem mem[XP70_MEM_MAX];
+	void __iomem *slimcore;
+	void __iomem *peri;
+	struct clk *clks[XP70_MAX_CLK];
+};
+
+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
+
+#endif
-- 
1.9.1

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

* [PATCH v4 02/18] ARM: multi_v7_defconfig: enable st xp70 rproc driver.
  2016-05-25 16:06 ` Peter Griffin
  (?)
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This is used by other device drivers whose IP is based
around the xp70 slim core (such as fdma) to load and
boot the firmware in the slimcore.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 2823490..d319d8f 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -503,6 +503,7 @@ CONFIG_REGULATOR_TPS6586X=y
 CONFIG_REGULATOR_TPS65910=y
 CONFIG_REGULATOR_TWL4030=y
 CONFIG_REGULATOR_VEXPRESS=y
+CONFIG_ST_XP70_REMOTEPROC=m
 CONFIG_MEDIA_SUPPORT=m
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
-- 
1.9.1

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

* [PATCH v4 02/18] ARM: multi_v7_defconfig: enable st xp70 rproc driver.
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, devicetree, linux-remoteproc, lee.jones, dmaengine

This is used by other device drivers whose IP is based
around the xp70 slim core (such as fdma) to load and
boot the firmware in the slimcore.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 2823490..d319d8f 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -503,6 +503,7 @@ CONFIG_REGULATOR_TPS6586X=y
 CONFIG_REGULATOR_TPS65910=y
 CONFIG_REGULATOR_TWL4030=y
 CONFIG_REGULATOR_VEXPRESS=y
+CONFIG_ST_XP70_REMOTEPROC=m
 CONFIG_MEDIA_SUPPORT=m
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
-- 
1.9.1

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

* [PATCH v4 02/18] ARM: multi_v7_defconfig: enable st xp70 rproc driver.
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This is used by other device drivers whose IP is based
around the xp70 slim core (such as fdma) to load and
boot the firmware in the slimcore.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 2823490..d319d8f 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -503,6 +503,7 @@ CONFIG_REGULATOR_TPS6586X=y
 CONFIG_REGULATOR_TPS65910=y
 CONFIG_REGULATOR_TWL4030=y
 CONFIG_REGULATOR_VEXPRESS=y
+CONFIG_ST_XP70_REMOTEPROC=m
 CONFIG_MEDIA_SUPPORT=m
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
-- 
1.9.1

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

* [PATCH v4 03/18] MAINTAINERS: Add st xp70 rproc driver to STi section.
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch adds the xp70 rproc driver to the STi section
of the MAINTAINERS file.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 61a323a..de99aec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1647,6 +1647,7 @@ F:	drivers/phy/phy-miphy365x.c
 F:	drivers/phy/phy-stih407-usb.c
 F:	drivers/phy/phy-stih41x-usb.c
 F:	drivers/pinctrl/pinctrl-st.c
+F:	drivers/remoteproc/st_xp70_rproc.c
 F:	drivers/reset/sti/
 F:	drivers/rtc/rtc-st-lpc.c
 F:	drivers/tty/serial/st-asc.c
@@ -1655,6 +1656,7 @@ F:	drivers/usb/host/ehci-st.c
 F:	drivers/usb/host/ohci-st.c
 F:	drivers/watchdog/st_lpc_wdt.c
 F:	drivers/ata/ahci_st.c
+F:	include/linux/remoteproc/st_xp70_rproc.h
 
 ARM/STM32 ARCHITECTURE
 M:	Maxime Coquelin <mcoquelin.stm32@gmail.com>
-- 
1.9.1

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

* [PATCH v4 03/18] MAINTAINERS: Add st xp70 rproc driver to STi section.
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the xp70 rproc driver to the STi section
of the MAINTAINERS file.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 61a323a..de99aec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1647,6 +1647,7 @@ F:	drivers/phy/phy-miphy365x.c
 F:	drivers/phy/phy-stih407-usb.c
 F:	drivers/phy/phy-stih41x-usb.c
 F:	drivers/pinctrl/pinctrl-st.c
+F:	drivers/remoteproc/st_xp70_rproc.c
 F:	drivers/reset/sti/
 F:	drivers/rtc/rtc-st-lpc.c
 F:	drivers/tty/serial/st-asc.c
@@ -1655,6 +1656,7 @@ F:	drivers/usb/host/ehci-st.c
 F:	drivers/usb/host/ohci-st.c
 F:	drivers/watchdog/st_lpc_wdt.c
 F:	drivers/ata/ahci_st.c
+F:	include/linux/remoteproc/st_xp70_rproc.h
 
 ARM/STM32 ARCHITECTURE
 M:	Maxime Coquelin <mcoquelin.stm32@gmail.com>
-- 
1.9.1

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

* [PATCH v4 04/18] dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding documentation
  2016-05-25 16:06 ` Peter Griffin
  (?)
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine,
	linux-remoteproc, Ludovic Barre

This patch adds the DT binding documentation for the FDMA constroller
found on STi based chipsets from STMicroelectronics.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 Documentation/devicetree/bindings/dma/st_fdma.txt | 87 +++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt

diff --git a/Documentation/devicetree/bindings/dma/st_fdma.txt b/Documentation/devicetree/bindings/dma/st_fdma.txt
new file mode 100644
index 0000000..8fd60a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/st_fdma.txt
@@ -0,0 +1,87 @@
+* STMicroelectronics Flexible Direct Memory Access Device Tree bindings
+
+The FDMA is a general-purpose direct memory access controller capable of
+supporting 16 independent DMA channels. It accepts up to 32 DMA requests.
+The FDMA is based on a Slim processor which requires a firmware.
+
+* FDMA Controller
+
+Required properties:
+- compatible	: Should be one of
+		 - st,stih407-fdma-mpe31-11, "st,xp70-rproc";
+		 - st,stih407-fdma-mpe31-12, "st,xp70-rproc";
+		 - st,stih407-fdma-mpe31-13, "st,xp70-rproc";
+- reg		: Should contain an entry for each name in reg-names
+- reg-names	: Must contain "slimcore", "dmem", "peripherals", "imem" entries
+- interrupts	: Should contain one interrupt shared by all channels
+- dma-channels	: Number of channels supported by the controller
+- #dma-cells	: Must be <3>. See DMA client section below
+- clocks	: Must contain an entry for each clock
+See: Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+
+Example:
+
+	fdma0: dma-controller@8e20000 {
+		compatible = "st,stih407-fdma-mpe31-11", "st,xp70-rproc";
+		reg = <0x8e20000 0x8000>,
+		      <0x8e30000 0x3000>,
+		      <0x8e37000 0x1000>,
+		      <0x8e38000 0x8000>;
+		reg-names = "slimcore", "dmem", "peripherals", "imem";
+		clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+		interrupts = <GIC_SPI 5 IRQ_TYPE_NONE>;
+		dma-channels = <16>;
+		#dma-cells = <3>;
+	};
+
+* DMA client
+
+Required properties:
+- dmas: Comma separated list of dma channel requests
+- dma-names: Names of the aforementioned requested channels
+
+Each dmas request consists of 4 cells:
+1. A phandle pointing to the FDMA controller
+2. The request line number
+3. A 32bit mask specifying (see include/linux/platform_data/dma-st-fdma.h)
+ -bit 2-0: Holdoff value, dreq will be masked for
+	0x0: 0-0.5us
+	0x1: 0.5-1us
+	0x2: 1-1.5us
+ -bit 17: data swap
+	0x0: disabled
+	0x1: enabled
+ -bit 21: Increment Address
+	0x0: no address increment between transfers
+	0x1: increment address between transfers
+ -bit 22: 2 STBus Initiator Coprocessor interface
+	0x0: high priority port
+	0x1: low priority port
+4. transfers type
+ 0 free running
+ 1 paced
+
+Example:
+
+	sti_uni_player2: sti-uni-player@2 {
+		compatible = "st,sti-uni-player";
+		status = "disabled";
+		#sound-dai-cells = <0>;
+		st,syscfg = <&syscfg_core>;
+		clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+		assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+		assigned-clock-parents = <&clk_s_d0_quadfs 2>;
+		assigned-clock-rates = <50000000>;
+		reg = <0x8D82000 0x158>;
+		interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
+		dmas = <&fdma0 4 0 1>;
+		dai-name = "Uni Player #1 (DAC)";
+		dma-names = "tx";
+		st,uniperiph-id = <2>;
+		st,version = <5>;
+		st,mode = "PCM";
+	};
-- 
1.9.1

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

* [PATCH v4 04/18] dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding documentation
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: devicetree, linux-remoteproc, peter.griffin, dmaengine,
	lee.jones, Ludovic Barre

This patch adds the DT binding documentation for the FDMA constroller
found on STi based chipsets from STMicroelectronics.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 Documentation/devicetree/bindings/dma/st_fdma.txt | 87 +++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt

diff --git a/Documentation/devicetree/bindings/dma/st_fdma.txt b/Documentation/devicetree/bindings/dma/st_fdma.txt
new file mode 100644
index 0000000..8fd60a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/st_fdma.txt
@@ -0,0 +1,87 @@
+* STMicroelectronics Flexible Direct Memory Access Device Tree bindings
+
+The FDMA is a general-purpose direct memory access controller capable of
+supporting 16 independent DMA channels. It accepts up to 32 DMA requests.
+The FDMA is based on a Slim processor which requires a firmware.
+
+* FDMA Controller
+
+Required properties:
+- compatible	: Should be one of
+		 - st,stih407-fdma-mpe31-11, "st,xp70-rproc";
+		 - st,stih407-fdma-mpe31-12, "st,xp70-rproc";
+		 - st,stih407-fdma-mpe31-13, "st,xp70-rproc";
+- reg		: Should contain an entry for each name in reg-names
+- reg-names	: Must contain "slimcore", "dmem", "peripherals", "imem" entries
+- interrupts	: Should contain one interrupt shared by all channels
+- dma-channels	: Number of channels supported by the controller
+- #dma-cells	: Must be <3>. See DMA client section below
+- clocks	: Must contain an entry for each clock
+See: Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+
+Example:
+
+	fdma0: dma-controller@8e20000 {
+		compatible = "st,stih407-fdma-mpe31-11", "st,xp70-rproc";
+		reg = <0x8e20000 0x8000>,
+		      <0x8e30000 0x3000>,
+		      <0x8e37000 0x1000>,
+		      <0x8e38000 0x8000>;
+		reg-names = "slimcore", "dmem", "peripherals", "imem";
+		clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+		interrupts = <GIC_SPI 5 IRQ_TYPE_NONE>;
+		dma-channels = <16>;
+		#dma-cells = <3>;
+	};
+
+* DMA client
+
+Required properties:
+- dmas: Comma separated list of dma channel requests
+- dma-names: Names of the aforementioned requested channels
+
+Each dmas request consists of 4 cells:
+1. A phandle pointing to the FDMA controller
+2. The request line number
+3. A 32bit mask specifying (see include/linux/platform_data/dma-st-fdma.h)
+ -bit 2-0: Holdoff value, dreq will be masked for
+	0x0: 0-0.5us
+	0x1: 0.5-1us
+	0x2: 1-1.5us
+ -bit 17: data swap
+	0x0: disabled
+	0x1: enabled
+ -bit 21: Increment Address
+	0x0: no address increment between transfers
+	0x1: increment address between transfers
+ -bit 22: 2 STBus Initiator Coprocessor interface
+	0x0: high priority port
+	0x1: low priority port
+4. transfers type
+ 0 free running
+ 1 paced
+
+Example:
+
+	sti_uni_player2: sti-uni-player@2 {
+		compatible = "st,sti-uni-player";
+		status = "disabled";
+		#sound-dai-cells = <0>;
+		st,syscfg = <&syscfg_core>;
+		clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+		assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+		assigned-clock-parents = <&clk_s_d0_quadfs 2>;
+		assigned-clock-rates = <50000000>;
+		reg = <0x8D82000 0x158>;
+		interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
+		dmas = <&fdma0 4 0 1>;
+		dai-name = "Uni Player #1 (DAC)";
+		dma-names = "tx";
+		st,uniperiph-id = <2>;
+		st,version = <5>;
+		st,mode = "PCM";
+	};
-- 
1.9.1

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

* [PATCH v4 04/18] dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding documentation
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the DT binding documentation for the FDMA constroller
found on STi based chipsets from STMicroelectronics.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 Documentation/devicetree/bindings/dma/st_fdma.txt | 87 +++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt

diff --git a/Documentation/devicetree/bindings/dma/st_fdma.txt b/Documentation/devicetree/bindings/dma/st_fdma.txt
new file mode 100644
index 0000000..8fd60a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/st_fdma.txt
@@ -0,0 +1,87 @@
+* STMicroelectronics Flexible Direct Memory Access Device Tree bindings
+
+The FDMA is a general-purpose direct memory access controller capable of
+supporting 16 independent DMA channels. It accepts up to 32 DMA requests.
+The FDMA is based on a Slim processor which requires a firmware.
+
+* FDMA Controller
+
+Required properties:
+- compatible	: Should be one of
+		 - st,stih407-fdma-mpe31-11, "st,xp70-rproc";
+		 - st,stih407-fdma-mpe31-12, "st,xp70-rproc";
+		 - st,stih407-fdma-mpe31-13, "st,xp70-rproc";
+- reg		: Should contain an entry for each name in reg-names
+- reg-names	: Must contain "slimcore", "dmem", "peripherals", "imem" entries
+- interrupts	: Should contain one interrupt shared by all channels
+- dma-channels	: Number of channels supported by the controller
+- #dma-cells	: Must be <3>. See DMA client section below
+- clocks	: Must contain an entry for each clock
+See: Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+
+Example:
+
+	fdma0: dma-controller at 8e20000 {
+		compatible = "st,stih407-fdma-mpe31-11", "st,xp70-rproc";
+		reg = <0x8e20000 0x8000>,
+		      <0x8e30000 0x3000>,
+		      <0x8e37000 0x1000>,
+		      <0x8e38000 0x8000>;
+		reg-names = "slimcore", "dmem", "peripherals", "imem";
+		clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+			 <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+		interrupts = <GIC_SPI 5 IRQ_TYPE_NONE>;
+		dma-channels = <16>;
+		#dma-cells = <3>;
+	};
+
+* DMA client
+
+Required properties:
+- dmas: Comma separated list of dma channel requests
+- dma-names: Names of the aforementioned requested channels
+
+Each dmas request consists of 4 cells:
+1. A phandle pointing to the FDMA controller
+2. The request line number
+3. A 32bit mask specifying (see include/linux/platform_data/dma-st-fdma.h)
+ -bit 2-0: Holdoff value, dreq will be masked for
+	0x0: 0-0.5us
+	0x1: 0.5-1us
+	0x2: 1-1.5us
+ -bit 17: data swap
+	0x0: disabled
+	0x1: enabled
+ -bit 21: Increment Address
+	0x0: no address increment between transfers
+	0x1: increment address between transfers
+ -bit 22: 2 STBus Initiator Coprocessor interface
+	0x0: high priority port
+	0x1: low priority port
+4. transfers type
+ 0 free running
+ 1 paced
+
+Example:
+
+	sti_uni_player2: sti-uni-player at 2 {
+		compatible = "st,sti-uni-player";
+		status = "disabled";
+		#sound-dai-cells = <0>;
+		st,syscfg = <&syscfg_core>;
+		clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+		assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+		assigned-clock-parents = <&clk_s_d0_quadfs 2>;
+		assigned-clock-rates = <50000000>;
+		reg = <0x8D82000 0x158>;
+		interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
+		dmas = <&fdma0 4 0 1>;
+		dai-name = "Uni Player #1 (DAC)";
+		dma-names = "tx";
+		st,uniperiph-id = <2>;
+		st,version = <5>;
+		st,mode = "PCM";
+	};
-- 
1.9.1

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

* [PATCH v4 05/18] dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
  2016-05-25 16:06 ` Peter Griffin
  (?)
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine,
	linux-remoteproc, Ludovic Barre

This header file will also be used by the dma xbar driver in the
future.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/dma/st_fdma.h | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 243 insertions(+)
 create mode 100644 drivers/dma/st_fdma.h

diff --git a/drivers/dma/st_fdma.h b/drivers/dma/st_fdma.h
new file mode 100644
index 0000000..6921d21
--- /dev/null
+++ b/drivers/dma/st_fdma.h
@@ -0,0 +1,243 @@
+/*
+ * st_fdma.h
+ *
+ * Copyright (C) 2014 STMicroelectronics
+ * Author: Ludovic Barre <Ludovic.barre@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef __DMA_ST_FDMA_H
+#define __DMA_ST_FDMA_H
+
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/remoteproc/st_xp70_rproc.h>
+
+#include "virt-dma.h"
+
+#define ST_FDMA_NR_DREQS 32
+
+#define FW_NAME_SIZE 30
+
+/**
+ * struct st_fdma_generic_node - Free running/paced generic node
+ *
+ * @length: Length in bytes of a line in a 2D mem to mem
+ * @sstride: Stride, in bytes, between source lines in a 2D data move
+ * @dstride: Stride, in bytes, between destination lines in a 2D data move
+ */
+struct st_fdma_generic_node {
+	u32 length;
+	u32 sstride;
+	u32 dstride;
+};
+
+/**
+ * struct st_fdma_hw_node - Node structure used by fdma hw
+ *
+ * @next: Pointer to next node
+ * @control: Transfer Control Parameters
+ * @nbytes: Number of Bytes to read
+ * @saddr: Source address
+ * @daddr: Destination address
+ *
+ * @generic: generic node for free running/paced transfert type
+ * 2 others transfert type are possible, but not yet implemented
+ *
+ * The NODE structures must be aligned to a 32 byte boundary
+ */
+struct st_fdma_hw_node {
+	u32 next;
+	u32 control;
+	u32 nbytes;
+	u32 saddr;
+	u32 daddr;
+	union {
+		struct st_fdma_generic_node generic;
+	};
+} __aligned(32);
+
+/*
+ * node control parameters
+ */
+#define NODE_CTRL_REQ_MAP_MASK		GENMASK(4, 0)
+#define NODE_CTRL_REQ_MAP_FREE_RUN	0x0
+#define NODE_CTRL_REQ_MAP_DREQ(n)	((n) & NODE_CTRL_REQ_MAP_MASK)
+#define NODE_CTRL_REQ_MAP_EXT		NODE_CTRL_REQ_MAP_MASK
+#define NODE_CTRL_SRC_MASK		GENMASK(6, 5)
+#define NODE_CTRL_SRC_STATIC		BIT(5)
+#define NODE_CTRL_SRC_INCR		BIT(6)
+#define NODE_CTRL_DST_MASK		GENMASK(8, 7)
+#define NODE_CTRL_DST_STATIC		BIT(7)
+#define NODE_CTRL_DST_INCR		BIT(8)
+#define NODE_CTRL_SECURE		BIT(15)
+#define NODE_CTRL_PAUSE_EON		BIT(30)
+#define NODE_CTRL_INT_EON		BIT(31)
+
+/**
+ * struct st_fdma_sw_node - descriptor structure for link list
+ *
+ * @pdesc: Physical address of desc
+ * @node: link used for putting this into a channel queue
+ */
+struct st_fdma_sw_node {
+	dma_addr_t pdesc;
+	struct st_fdma_hw_node *desc;
+};
+
+#define NAME_SZ 10
+
+struct st_fdma_driverdata {
+	u32 id;
+	char name[NAME_SZ];
+};
+
+struct st_fdma_desc {
+	struct virt_dma_desc vdesc;
+	struct st_fdma_chan *fchan;
+	bool iscyclic;
+	unsigned int n_nodes;
+	struct st_fdma_sw_node node[];
+};
+
+enum st_fdma_type {
+	ST_FDMA_TYPE_FREE_RUN,
+	ST_FDMA_TYPE_PACED,
+};
+
+struct st_fdma_cfg {
+	struct device_node *of_node;
+	enum st_fdma_type type;
+	dma_addr_t dev_addr;
+	enum dma_transfer_direction dir;
+	int req_line; /* request line */
+	long req_ctrl; /* Request control */
+};
+
+struct st_fdma_chan {
+	struct st_fdma_dev *fdev;
+	struct dma_pool *node_pool;
+	struct dma_slave_config scfg;
+	struct st_fdma_cfg cfg;
+
+	int dreq_line;
+
+	struct virt_dma_chan vchan;
+	struct st_fdma_desc *fdesc;
+	enum dma_status	status;
+};
+
+struct st_fdma_dev {
+	struct device *dev;
+	const struct st_fdma_driverdata *drvdata;
+	struct dma_device dma_device;
+
+	struct st_xp70_rproc *xp70_rproc;
+
+	int irq;
+
+	struct st_fdma_chan *chans;
+
+	spinlock_t dreq_lock;
+	unsigned long dreq_mask;
+
+	u32 nr_channels;
+	char fw_name[FW_NAME_SIZE];
+
+	struct rproc *rproc;
+};
+
+/* Peripheral Registers*/
+
+#define FDMA_CMD_STA_OFST	0xFC0
+#define FDMA_CMD_SET_OFST	0xFC4
+#define FDMA_CMD_CLR_OFST	0xFC8
+#define FDMA_CMD_MASK_OFST	0xFCC
+#define FDMA_CMD_START(ch)		(0x1 << (ch << 1))
+#define FDMA_CMD_PAUSE(ch)		(0x2 << (ch << 1))
+#define FDMA_CMD_FLUSH(ch)		(0x3 << (ch << 1))
+
+#define FDMA_INT_STA_OFST	0xFD0
+#define FDMA_INT_STA_CH			0x1
+#define FDMA_INT_STA_ERR		0x2
+
+#define FDMA_INT_SET_OFST	0xFD4
+#define FDMA_INT_CLR_OFST	0xFD8
+#define FDMA_INT_MASK_OFST	0xFDC
+
+#define fdma_read(fdev, name) \
+	readl_relaxed((fdev)->xp70_rproc->peri + name)
+
+#define fdma_write(fdev, val, name) \
+	writel_relaxed((val), (fdev)->xp70_rproc->peri + name)
+
+/* fchan interface (dmem)*/
+#define FDMA_CH_CMD_OFST	0x200
+#define FDMA_CH_CMD_STA_MASK		GENMASK(1, 0)
+#define FDMA_CH_CMD_STA_IDLE		(0x0)
+#define FDMA_CH_CMD_STA_START		(0x1)
+#define FDMA_CH_CMD_STA_RUNNING		(0x2)
+#define FDMA_CH_CMD_STA_PAUSED		(0x3)
+#define FDMA_CH_CMD_ERR_MASK		GENMASK(4, 2)
+#define FDMA_CH_CMD_ERR_INT		(0x0 << 2)
+#define FDMA_CH_CMD_ERR_NAND		(0x1 << 2)
+#define FDMA_CH_CMD_ERR_MCHI		(0x2 << 2)
+#define FDMA_CH_CMD_DATA_MASK		GENMASK(31, 5)
+#define fchan_read(fchan, name) \
+	readl_relaxed((fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * 0x4 \
+			+ name)
+
+#define fchan_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * 0x4 \
+			+ name)
+
+/* req interface */
+#define FDMA_REQ_CTRL_OFST	0x240
+#define dreq_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ fchan->dreq_line * 0x04 \
+			+ name)
+/* node interface */
+#define FDMA_NODE_SZ 128
+#define FDMA_PTRN_OFST		0x800
+#define FDMA_CNTN_OFST		0x808
+#define FDMA_SADDRN_OFST	0x80c
+#define FDMA_DADDRN_OFST	0x810
+#define fnode_read(fchan, name) \
+	readl_relaxed((fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \
+			+ name)
+
+#define fnode_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \
+			+ name)
+
+/*
+ * request control bits
+ */
+#define REQ_CTRL_NUM_OPS_MASK		GENMASK(31, 24)
+#define REQ_CTRL_NUM_OPS(n)		(REQ_CTRL_NUM_OPS_MASK & ((n) << 24))
+#define REQ_CTRL_INITIATOR_MASK		BIT(22)
+#define	REQ_CTRL_INIT0			(0x0 << 22)
+#define	REQ_CTRL_INIT1			(0x1 << 22)
+#define REQ_CTRL_INC_ADDR_ON		BIT(21)
+#define REQ_CTRL_DATA_SWAP_ON		BIT(17)
+#define REQ_CTRL_WNR			BIT(14)
+#define REQ_CTRL_OPCODE_MASK		GENMASK(7, 4)
+#define REQ_CTRL_OPCODE_LD_ST1		(0x0 << 4)
+#define REQ_CTRL_OPCODE_LD_ST2		(0x1 << 4)
+#define REQ_CTRL_OPCODE_LD_ST4		(0x2 << 4)
+#define REQ_CTRL_OPCODE_LD_ST8		(0x3 << 4)
+#define REQ_CTRL_OPCODE_LD_ST16		(0x4 << 4)
+#define REQ_CTRL_OPCODE_LD_ST32		(0x5 << 4)
+#define REQ_CTRL_OPCODE_LD_ST64		(0x6 << 4)
+#define REQ_CTRL_HOLDOFF_MASK		GENMASK(2, 0)
+#define REQ_CTRL_HOLDOFF(n)		((n) & REQ_CTRL_HOLDOFF_MASK)
+
+/* bits used by client to configure request control */
+#define REQ_CTRL_CFG_MASK (REQ_CTRL_HOLDOFF_MASK | REQ_CTRL_DATA_SWAP_ON \
+			| REQ_CTRL_INC_ADDR_ON | REQ_CTRL_INITIATOR_MASK)
+
+#endif	/* __DMA_ST_FDMA_H */
-- 
1.9.1

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

* [PATCH v4 05/18] dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: devicetree, linux-remoteproc, peter.griffin, dmaengine,
	lee.jones, Ludovic Barre

This header file will also be used by the dma xbar driver in the
future.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/dma/st_fdma.h | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 243 insertions(+)
 create mode 100644 drivers/dma/st_fdma.h

diff --git a/drivers/dma/st_fdma.h b/drivers/dma/st_fdma.h
new file mode 100644
index 0000000..6921d21
--- /dev/null
+++ b/drivers/dma/st_fdma.h
@@ -0,0 +1,243 @@
+/*
+ * st_fdma.h
+ *
+ * Copyright (C) 2014 STMicroelectronics
+ * Author: Ludovic Barre <Ludovic.barre@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef __DMA_ST_FDMA_H
+#define __DMA_ST_FDMA_H
+
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/remoteproc/st_xp70_rproc.h>
+
+#include "virt-dma.h"
+
+#define ST_FDMA_NR_DREQS 32
+
+#define FW_NAME_SIZE 30
+
+/**
+ * struct st_fdma_generic_node - Free running/paced generic node
+ *
+ * @length: Length in bytes of a line in a 2D mem to mem
+ * @sstride: Stride, in bytes, between source lines in a 2D data move
+ * @dstride: Stride, in bytes, between destination lines in a 2D data move
+ */
+struct st_fdma_generic_node {
+	u32 length;
+	u32 sstride;
+	u32 dstride;
+};
+
+/**
+ * struct st_fdma_hw_node - Node structure used by fdma hw
+ *
+ * @next: Pointer to next node
+ * @control: Transfer Control Parameters
+ * @nbytes: Number of Bytes to read
+ * @saddr: Source address
+ * @daddr: Destination address
+ *
+ * @generic: generic node for free running/paced transfert type
+ * 2 others transfert type are possible, but not yet implemented
+ *
+ * The NODE structures must be aligned to a 32 byte boundary
+ */
+struct st_fdma_hw_node {
+	u32 next;
+	u32 control;
+	u32 nbytes;
+	u32 saddr;
+	u32 daddr;
+	union {
+		struct st_fdma_generic_node generic;
+	};
+} __aligned(32);
+
+/*
+ * node control parameters
+ */
+#define NODE_CTRL_REQ_MAP_MASK		GENMASK(4, 0)
+#define NODE_CTRL_REQ_MAP_FREE_RUN	0x0
+#define NODE_CTRL_REQ_MAP_DREQ(n)	((n) & NODE_CTRL_REQ_MAP_MASK)
+#define NODE_CTRL_REQ_MAP_EXT		NODE_CTRL_REQ_MAP_MASK
+#define NODE_CTRL_SRC_MASK		GENMASK(6, 5)
+#define NODE_CTRL_SRC_STATIC		BIT(5)
+#define NODE_CTRL_SRC_INCR		BIT(6)
+#define NODE_CTRL_DST_MASK		GENMASK(8, 7)
+#define NODE_CTRL_DST_STATIC		BIT(7)
+#define NODE_CTRL_DST_INCR		BIT(8)
+#define NODE_CTRL_SECURE		BIT(15)
+#define NODE_CTRL_PAUSE_EON		BIT(30)
+#define NODE_CTRL_INT_EON		BIT(31)
+
+/**
+ * struct st_fdma_sw_node - descriptor structure for link list
+ *
+ * @pdesc: Physical address of desc
+ * @node: link used for putting this into a channel queue
+ */
+struct st_fdma_sw_node {
+	dma_addr_t pdesc;
+	struct st_fdma_hw_node *desc;
+};
+
+#define NAME_SZ 10
+
+struct st_fdma_driverdata {
+	u32 id;
+	char name[NAME_SZ];
+};
+
+struct st_fdma_desc {
+	struct virt_dma_desc vdesc;
+	struct st_fdma_chan *fchan;
+	bool iscyclic;
+	unsigned int n_nodes;
+	struct st_fdma_sw_node node[];
+};
+
+enum st_fdma_type {
+	ST_FDMA_TYPE_FREE_RUN,
+	ST_FDMA_TYPE_PACED,
+};
+
+struct st_fdma_cfg {
+	struct device_node *of_node;
+	enum st_fdma_type type;
+	dma_addr_t dev_addr;
+	enum dma_transfer_direction dir;
+	int req_line; /* request line */
+	long req_ctrl; /* Request control */
+};
+
+struct st_fdma_chan {
+	struct st_fdma_dev *fdev;
+	struct dma_pool *node_pool;
+	struct dma_slave_config scfg;
+	struct st_fdma_cfg cfg;
+
+	int dreq_line;
+
+	struct virt_dma_chan vchan;
+	struct st_fdma_desc *fdesc;
+	enum dma_status	status;
+};
+
+struct st_fdma_dev {
+	struct device *dev;
+	const struct st_fdma_driverdata *drvdata;
+	struct dma_device dma_device;
+
+	struct st_xp70_rproc *xp70_rproc;
+
+	int irq;
+
+	struct st_fdma_chan *chans;
+
+	spinlock_t dreq_lock;
+	unsigned long dreq_mask;
+
+	u32 nr_channels;
+	char fw_name[FW_NAME_SIZE];
+
+	struct rproc *rproc;
+};
+
+/* Peripheral Registers*/
+
+#define FDMA_CMD_STA_OFST	0xFC0
+#define FDMA_CMD_SET_OFST	0xFC4
+#define FDMA_CMD_CLR_OFST	0xFC8
+#define FDMA_CMD_MASK_OFST	0xFCC
+#define FDMA_CMD_START(ch)		(0x1 << (ch << 1))
+#define FDMA_CMD_PAUSE(ch)		(0x2 << (ch << 1))
+#define FDMA_CMD_FLUSH(ch)		(0x3 << (ch << 1))
+
+#define FDMA_INT_STA_OFST	0xFD0
+#define FDMA_INT_STA_CH			0x1
+#define FDMA_INT_STA_ERR		0x2
+
+#define FDMA_INT_SET_OFST	0xFD4
+#define FDMA_INT_CLR_OFST	0xFD8
+#define FDMA_INT_MASK_OFST	0xFDC
+
+#define fdma_read(fdev, name) \
+	readl_relaxed((fdev)->xp70_rproc->peri + name)
+
+#define fdma_write(fdev, val, name) \
+	writel_relaxed((val), (fdev)->xp70_rproc->peri + name)
+
+/* fchan interface (dmem)*/
+#define FDMA_CH_CMD_OFST	0x200
+#define FDMA_CH_CMD_STA_MASK		GENMASK(1, 0)
+#define FDMA_CH_CMD_STA_IDLE		(0x0)
+#define FDMA_CH_CMD_STA_START		(0x1)
+#define FDMA_CH_CMD_STA_RUNNING		(0x2)
+#define FDMA_CH_CMD_STA_PAUSED		(0x3)
+#define FDMA_CH_CMD_ERR_MASK		GENMASK(4, 2)
+#define FDMA_CH_CMD_ERR_INT		(0x0 << 2)
+#define FDMA_CH_CMD_ERR_NAND		(0x1 << 2)
+#define FDMA_CH_CMD_ERR_MCHI		(0x2 << 2)
+#define FDMA_CH_CMD_DATA_MASK		GENMASK(31, 5)
+#define fchan_read(fchan, name) \
+	readl_relaxed((fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * 0x4 \
+			+ name)
+
+#define fchan_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * 0x4 \
+			+ name)
+
+/* req interface */
+#define FDMA_REQ_CTRL_OFST	0x240
+#define dreq_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ fchan->dreq_line * 0x04 \
+			+ name)
+/* node interface */
+#define FDMA_NODE_SZ 128
+#define FDMA_PTRN_OFST		0x800
+#define FDMA_CNTN_OFST		0x808
+#define FDMA_SADDRN_OFST	0x80c
+#define FDMA_DADDRN_OFST	0x810
+#define fnode_read(fchan, name) \
+	readl_relaxed((fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \
+			+ name)
+
+#define fnode_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \
+			+ name)
+
+/*
+ * request control bits
+ */
+#define REQ_CTRL_NUM_OPS_MASK		GENMASK(31, 24)
+#define REQ_CTRL_NUM_OPS(n)		(REQ_CTRL_NUM_OPS_MASK & ((n) << 24))
+#define REQ_CTRL_INITIATOR_MASK		BIT(22)
+#define	REQ_CTRL_INIT0			(0x0 << 22)
+#define	REQ_CTRL_INIT1			(0x1 << 22)
+#define REQ_CTRL_INC_ADDR_ON		BIT(21)
+#define REQ_CTRL_DATA_SWAP_ON		BIT(17)
+#define REQ_CTRL_WNR			BIT(14)
+#define REQ_CTRL_OPCODE_MASK		GENMASK(7, 4)
+#define REQ_CTRL_OPCODE_LD_ST1		(0x0 << 4)
+#define REQ_CTRL_OPCODE_LD_ST2		(0x1 << 4)
+#define REQ_CTRL_OPCODE_LD_ST4		(0x2 << 4)
+#define REQ_CTRL_OPCODE_LD_ST8		(0x3 << 4)
+#define REQ_CTRL_OPCODE_LD_ST16		(0x4 << 4)
+#define REQ_CTRL_OPCODE_LD_ST32		(0x5 << 4)
+#define REQ_CTRL_OPCODE_LD_ST64		(0x6 << 4)
+#define REQ_CTRL_HOLDOFF_MASK		GENMASK(2, 0)
+#define REQ_CTRL_HOLDOFF(n)		((n) & REQ_CTRL_HOLDOFF_MASK)
+
+/* bits used by client to configure request control */
+#define REQ_CTRL_CFG_MASK (REQ_CTRL_HOLDOFF_MASK | REQ_CTRL_DATA_SWAP_ON \
+			| REQ_CTRL_INC_ADDR_ON | REQ_CTRL_INITIATOR_MASK)
+
+#endif	/* __DMA_ST_FDMA_H */
-- 
1.9.1

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

* [PATCH v4 05/18] dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This header file will also be used by the dma xbar driver in the
future.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/dma/st_fdma.h | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 243 insertions(+)
 create mode 100644 drivers/dma/st_fdma.h

diff --git a/drivers/dma/st_fdma.h b/drivers/dma/st_fdma.h
new file mode 100644
index 0000000..6921d21
--- /dev/null
+++ b/drivers/dma/st_fdma.h
@@ -0,0 +1,243 @@
+/*
+ * st_fdma.h
+ *
+ * Copyright (C) 2014 STMicroelectronics
+ * Author: Ludovic Barre <Ludovic.barre@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef __DMA_ST_FDMA_H
+#define __DMA_ST_FDMA_H
+
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/remoteproc/st_xp70_rproc.h>
+
+#include "virt-dma.h"
+
+#define ST_FDMA_NR_DREQS 32
+
+#define FW_NAME_SIZE 30
+
+/**
+ * struct st_fdma_generic_node - Free running/paced generic node
+ *
+ * @length: Length in bytes of a line in a 2D mem to mem
+ * @sstride: Stride, in bytes, between source lines in a 2D data move
+ * @dstride: Stride, in bytes, between destination lines in a 2D data move
+ */
+struct st_fdma_generic_node {
+	u32 length;
+	u32 sstride;
+	u32 dstride;
+};
+
+/**
+ * struct st_fdma_hw_node - Node structure used by fdma hw
+ *
+ * @next: Pointer to next node
+ * @control: Transfer Control Parameters
+ * @nbytes: Number of Bytes to read
+ * @saddr: Source address
+ * @daddr: Destination address
+ *
+ * @generic: generic node for free running/paced transfert type
+ * 2 others transfert type are possible, but not yet implemented
+ *
+ * The NODE structures must be aligned to a 32 byte boundary
+ */
+struct st_fdma_hw_node {
+	u32 next;
+	u32 control;
+	u32 nbytes;
+	u32 saddr;
+	u32 daddr;
+	union {
+		struct st_fdma_generic_node generic;
+	};
+} __aligned(32);
+
+/*
+ * node control parameters
+ */
+#define NODE_CTRL_REQ_MAP_MASK		GENMASK(4, 0)
+#define NODE_CTRL_REQ_MAP_FREE_RUN	0x0
+#define NODE_CTRL_REQ_MAP_DREQ(n)	((n) & NODE_CTRL_REQ_MAP_MASK)
+#define NODE_CTRL_REQ_MAP_EXT		NODE_CTRL_REQ_MAP_MASK
+#define NODE_CTRL_SRC_MASK		GENMASK(6, 5)
+#define NODE_CTRL_SRC_STATIC		BIT(5)
+#define NODE_CTRL_SRC_INCR		BIT(6)
+#define NODE_CTRL_DST_MASK		GENMASK(8, 7)
+#define NODE_CTRL_DST_STATIC		BIT(7)
+#define NODE_CTRL_DST_INCR		BIT(8)
+#define NODE_CTRL_SECURE		BIT(15)
+#define NODE_CTRL_PAUSE_EON		BIT(30)
+#define NODE_CTRL_INT_EON		BIT(31)
+
+/**
+ * struct st_fdma_sw_node - descriptor structure for link list
+ *
+ * @pdesc: Physical address of desc
+ * @node: link used for putting this into a channel queue
+ */
+struct st_fdma_sw_node {
+	dma_addr_t pdesc;
+	struct st_fdma_hw_node *desc;
+};
+
+#define NAME_SZ 10
+
+struct st_fdma_driverdata {
+	u32 id;
+	char name[NAME_SZ];
+};
+
+struct st_fdma_desc {
+	struct virt_dma_desc vdesc;
+	struct st_fdma_chan *fchan;
+	bool iscyclic;
+	unsigned int n_nodes;
+	struct st_fdma_sw_node node[];
+};
+
+enum st_fdma_type {
+	ST_FDMA_TYPE_FREE_RUN,
+	ST_FDMA_TYPE_PACED,
+};
+
+struct st_fdma_cfg {
+	struct device_node *of_node;
+	enum st_fdma_type type;
+	dma_addr_t dev_addr;
+	enum dma_transfer_direction dir;
+	int req_line; /* request line */
+	long req_ctrl; /* Request control */
+};
+
+struct st_fdma_chan {
+	struct st_fdma_dev *fdev;
+	struct dma_pool *node_pool;
+	struct dma_slave_config scfg;
+	struct st_fdma_cfg cfg;
+
+	int dreq_line;
+
+	struct virt_dma_chan vchan;
+	struct st_fdma_desc *fdesc;
+	enum dma_status	status;
+};
+
+struct st_fdma_dev {
+	struct device *dev;
+	const struct st_fdma_driverdata *drvdata;
+	struct dma_device dma_device;
+
+	struct st_xp70_rproc *xp70_rproc;
+
+	int irq;
+
+	struct st_fdma_chan *chans;
+
+	spinlock_t dreq_lock;
+	unsigned long dreq_mask;
+
+	u32 nr_channels;
+	char fw_name[FW_NAME_SIZE];
+
+	struct rproc *rproc;
+};
+
+/* Peripheral Registers*/
+
+#define FDMA_CMD_STA_OFST	0xFC0
+#define FDMA_CMD_SET_OFST	0xFC4
+#define FDMA_CMD_CLR_OFST	0xFC8
+#define FDMA_CMD_MASK_OFST	0xFCC
+#define FDMA_CMD_START(ch)		(0x1 << (ch << 1))
+#define FDMA_CMD_PAUSE(ch)		(0x2 << (ch << 1))
+#define FDMA_CMD_FLUSH(ch)		(0x3 << (ch << 1))
+
+#define FDMA_INT_STA_OFST	0xFD0
+#define FDMA_INT_STA_CH			0x1
+#define FDMA_INT_STA_ERR		0x2
+
+#define FDMA_INT_SET_OFST	0xFD4
+#define FDMA_INT_CLR_OFST	0xFD8
+#define FDMA_INT_MASK_OFST	0xFDC
+
+#define fdma_read(fdev, name) \
+	readl_relaxed((fdev)->xp70_rproc->peri + name)
+
+#define fdma_write(fdev, val, name) \
+	writel_relaxed((val), (fdev)->xp70_rproc->peri + name)
+
+/* fchan interface (dmem)*/
+#define FDMA_CH_CMD_OFST	0x200
+#define FDMA_CH_CMD_STA_MASK		GENMASK(1, 0)
+#define FDMA_CH_CMD_STA_IDLE		(0x0)
+#define FDMA_CH_CMD_STA_START		(0x1)
+#define FDMA_CH_CMD_STA_RUNNING		(0x2)
+#define FDMA_CH_CMD_STA_PAUSED		(0x3)
+#define FDMA_CH_CMD_ERR_MASK		GENMASK(4, 2)
+#define FDMA_CH_CMD_ERR_INT		(0x0 << 2)
+#define FDMA_CH_CMD_ERR_NAND		(0x1 << 2)
+#define FDMA_CH_CMD_ERR_MCHI		(0x2 << 2)
+#define FDMA_CH_CMD_DATA_MASK		GENMASK(31, 5)
+#define fchan_read(fchan, name) \
+	readl_relaxed((fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * 0x4 \
+			+ name)
+
+#define fchan_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * 0x4 \
+			+ name)
+
+/* req interface */
+#define FDMA_REQ_CTRL_OFST	0x240
+#define dreq_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ fchan->dreq_line * 0x04 \
+			+ name)
+/* node interface */
+#define FDMA_NODE_SZ 128
+#define FDMA_PTRN_OFST		0x800
+#define FDMA_CNTN_OFST		0x808
+#define FDMA_SADDRN_OFST	0x80c
+#define FDMA_DADDRN_OFST	0x810
+#define fnode_read(fchan, name) \
+	readl_relaxed((fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \
+			+ name)
+
+#define fnode_write(fchan, val, name) \
+	writel_relaxed((val), (fchan)->fdev->xp70_rproc->mem[DMEM].cpu_addr \
+			+ (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \
+			+ name)
+
+/*
+ * request control bits
+ */
+#define REQ_CTRL_NUM_OPS_MASK		GENMASK(31, 24)
+#define REQ_CTRL_NUM_OPS(n)		(REQ_CTRL_NUM_OPS_MASK & ((n) << 24))
+#define REQ_CTRL_INITIATOR_MASK		BIT(22)
+#define	REQ_CTRL_INIT0			(0x0 << 22)
+#define	REQ_CTRL_INIT1			(0x1 << 22)
+#define REQ_CTRL_INC_ADDR_ON		BIT(21)
+#define REQ_CTRL_DATA_SWAP_ON		BIT(17)
+#define REQ_CTRL_WNR			BIT(14)
+#define REQ_CTRL_OPCODE_MASK		GENMASK(7, 4)
+#define REQ_CTRL_OPCODE_LD_ST1		(0x0 << 4)
+#define REQ_CTRL_OPCODE_LD_ST2		(0x1 << 4)
+#define REQ_CTRL_OPCODE_LD_ST4		(0x2 << 4)
+#define REQ_CTRL_OPCODE_LD_ST8		(0x3 << 4)
+#define REQ_CTRL_OPCODE_LD_ST16		(0x4 << 4)
+#define REQ_CTRL_OPCODE_LD_ST32		(0x5 << 4)
+#define REQ_CTRL_OPCODE_LD_ST64		(0x6 << 4)
+#define REQ_CTRL_HOLDOFF_MASK		GENMASK(2, 0)
+#define REQ_CTRL_HOLDOFF(n)		((n) & REQ_CTRL_HOLDOFF_MASK)
+
+/* bits used by client to configure request control */
+#define REQ_CTRL_CFG_MASK (REQ_CTRL_HOLDOFF_MASK | REQ_CTRL_DATA_SWAP_ON \
+			| REQ_CTRL_INC_ADDR_ON | REQ_CTRL_INITIATOR_MASK)
+
+#endif	/* __DMA_ST_FDMA_H */
-- 
1.9.1

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

* [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
  2016-05-25 16:06 ` Peter Griffin
  (?)
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine,
	linux-remoteproc, Ludovic Barre

This patch adds support for the Flexible Direct Memory Access (FDMA) core
driver. The FDMA is a slim core CPU with a dedicated firmware.
It is a general purpose DMA controller capable of supporting 16
independent DMA channels. Data moves maybe from memory to memory
or between memory and paced latency critical real time targets and it
is found on al STi based chipsets.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/dma/Kconfig   |  12 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/st_fdma.c | 882 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 895 insertions(+)
 create mode 100644 drivers/dma/st_fdma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index d96d87c..a65b8b3 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -527,6 +527,18 @@ config ZX_DMA
 	help
 	  Support the DMA engine for ZTE ZX296702 platform devices.
 
+config ST_FDMA
+	tristate "ST FDMA dmaengine support"
+	depends on ARCH_STI || COMPILE_TEST
+        depends on ST_XP70_REMOTEPROC
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	help
+	  Enable support for ST FDMA controller.
+	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
+
+	  Say Y here if you have such a chipset.
+	  If unsure, say N.
 
 # driver files
 source "drivers/dma/bestcomm/Kconfig"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 6084127..b81ca99 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
 obj-$(CONFIG_TI_EDMA) += edma.o
 obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx296702_dma.o
+obj-$(CONFIG_ST_FDMA) += st_fdma.o
 
 obj-y += qcom/
 obj-y += xilinx/
diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
new file mode 100644
index 0000000..34496b0
--- /dev/null
+++ b/drivers/dma/st_fdma.c
@@ -0,0 +1,882 @@
+/*
+ * st_fdma.c
+ *
+ * Copyright (C) 2014 STMicroelectronics
+ * Author: Ludovic Barre <Ludovic.barre@st.com>
+ *	   Peter Griffin <peter.griffin@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
+#include <linux/firmware.h>
+#include <linux/elf.h>
+#include <linux/atomic.h>
+#include <linux/remoteproc.h>
+#include <linux/io.h>
+
+#include "st_fdma.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+static inline struct st_fdma_chan *to_st_fdma_chan(struct dma_chan *c)
+{
+	return container_of(c, struct st_fdma_chan, vchan.chan);
+}
+
+static struct st_fdma_desc *to_st_fdma_desc(struct virt_dma_desc *vd)
+{
+	return container_of(vd, struct st_fdma_desc, vdesc);
+}
+
+static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
+{
+	struct st_fdma_dev *fdev = fchan->fdev;
+	u32 req_line_cfg = fchan->cfg.req_line;
+	u32 dreq_line;
+	int try = 0;
+
+	/*
+	 * dreq_mask is shared for n channels of fdma, so all accesses must be
+	 * atomic. if the dreq_mask it change between ffz ant set_bit,
+	 * we retry
+	 */
+	do {
+		if (fdev->dreq_mask == ~0L) {
+			dev_err(fdev->dev, "No req lines available\n");
+			return -EINVAL;
+		}
+
+		if (try || req_line_cfg >= ST_FDMA_NR_DREQS) {
+			dev_err(fdev->dev, "Invalid or used req line\n");
+			return -EINVAL;
+		} else {
+			dreq_line = req_line_cfg;
+		}
+
+		try++;
+	} while (test_and_set_bit(dreq_line, &fdev->dreq_mask));
+
+	dev_dbg(fdev->dev, "get dreq_line:%d mask:%#lx\n",
+		dreq_line, fdev->dreq_mask);
+
+	return dreq_line;
+}
+
+static void st_fdma_dreq_put(struct st_fdma_chan *fchan)
+{
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line);
+	clear_bit(fchan->dreq_line, &fdev->dreq_mask);
+}
+
+static void st_fdma_xfer_desc(struct st_fdma_chan *fchan)
+{
+	struct virt_dma_desc *vdesc;
+	unsigned long nbytes, ch_cmd, cmd;
+
+	vdesc = vchan_next_desc(&fchan->vchan);
+	if (!vdesc)
+		return;
+
+	fchan->fdesc = to_st_fdma_desc(vdesc);
+	nbytes = fchan->fdesc->node[0].desc->nbytes;
+	cmd = FDMA_CMD_START(fchan->vchan.chan.chan_id);
+	ch_cmd = fchan->fdesc->node[0].pdesc | FDMA_CH_CMD_STA_START;
+
+	/* start the channel for the descriptor */
+	fnode_write(fchan, nbytes, FDMA_CNTN_OFST);
+	fchan_write(fchan, ch_cmd, FDMA_CH_CMD_OFST);
+	writel(cmd,
+		fchan->fdev->xp70_rproc->peri + FDMA_CMD_SET_OFST);
+
+	dev_dbg(fchan->fdev->dev, "start chan:%d\n", fchan->vchan.chan.chan_id);
+}
+
+static void st_fdma_ch_sta_update(struct st_fdma_chan *fchan,
+				  unsigned long int_sta)
+{
+	unsigned long ch_sta, ch_err;
+	int ch_id = fchan->vchan.chan.chan_id;
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	ch_sta = fchan_read(fchan, FDMA_CH_CMD_OFST);
+	ch_err = ch_sta & FDMA_CH_CMD_ERR_MASK;
+	ch_sta &= FDMA_CH_CMD_STA_MASK;
+
+	if (int_sta & FDMA_INT_STA_ERR) {
+		dev_warn(fdev->dev, "chan:%d, error:%ld\n", ch_id, ch_err);
+		fchan->status = DMA_ERROR;
+		return;
+	}
+
+	switch (ch_sta) {
+	case FDMA_CH_CMD_STA_PAUSED:
+		fchan->status = DMA_PAUSED;
+		break;
+	case FDMA_CH_CMD_STA_RUNNING:
+		fchan->status = DMA_IN_PROGRESS;
+		break;
+	}
+}
+
+static irqreturn_t st_fdma_irq_handler(int irq, void *dev_id)
+{
+	struct st_fdma_dev *fdev = dev_id;
+	irqreturn_t ret = IRQ_NONE;
+	struct st_fdma_chan *fchan = &fdev->chans[0];
+	unsigned long int_sta, clr;
+
+	int_sta = fdma_read(fdev, FDMA_INT_STA_OFST);
+	clr = int_sta;
+
+	for (; int_sta != 0 ; int_sta >>= 2, fchan++) {
+		if (!(int_sta & (FDMA_INT_STA_CH | FDMA_INT_STA_ERR)))
+			continue;
+
+		spin_lock(&fchan->vchan.lock);
+		st_fdma_ch_sta_update(fchan, int_sta);
+
+		if (fchan->fdesc) {
+			if (!fchan->fdesc->iscyclic) {
+				list_del(&fchan->fdesc->vdesc.node);
+				vchan_cookie_complete(&fchan->fdesc->vdesc);
+				fchan->fdesc = NULL;
+				fchan->status = DMA_COMPLETE;
+			} else {
+				vchan_cyclic_callback(&fchan->fdesc->vdesc);
+			}
+
+			/* Start the next descriptor (if available) */
+			if (!fchan->fdesc)
+				st_fdma_xfer_desc(fchan);
+		}
+
+		spin_unlock(&fchan->vchan.lock);
+		ret = IRQ_HANDLED;
+	}
+
+	fdma_write(fdev, clr, FDMA_INT_CLR_OFST);
+
+	return ret;
+}
+
+static struct dma_chan *st_fdma_of_xlate(struct of_phandle_args *dma_spec,
+					 struct of_dma *ofdma)
+{
+	struct st_fdma_dev *fdev = ofdma->of_dma_data;
+	struct dma_chan *chan;
+	struct st_fdma_chan *fchan;
+
+	if (dma_spec->args_count < 1)
+		return NULL;
+
+	chan = dma_get_any_slave_channel(&fdev->dma_device);
+	if (!chan)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	if (fchan->fdev->dma_device.dev->of_node != dma_spec->np)
+		return NULL;
+
+	fchan->cfg.of_node = dma_spec->np;
+	fchan->cfg.req_line = dma_spec->args[0];
+	fchan->cfg.req_ctrl = 0;
+	fchan->cfg.type = ST_FDMA_TYPE_FREE_RUN;
+
+	if (dma_spec->args_count > 1)
+		fchan->cfg.req_ctrl = dma_spec->args[1] & REQ_CTRL_CFG_MASK;
+
+	if (dma_spec->args_count > 2)
+		fchan->cfg.type = dma_spec->args[2];
+
+	if (fchan->cfg.type == ST_FDMA_TYPE_FREE_RUN) {
+		fchan->dreq_line = 0;
+	} else {
+		fchan->dreq_line = st_fdma_dreq_get(fchan);
+		if (IS_ERR_VALUE(fchan->dreq_line))
+			return NULL;
+	}
+
+	dev_dbg(fdev->dev, "xlate req_line:%d type:%d req_ctrl:%#lx\n",
+		fchan->cfg.req_line, fchan->cfg.type, fchan->cfg.req_ctrl);
+
+	return chan;
+}
+
+static void st_fdma_free_desc(struct virt_dma_desc *vdesc)
+{
+	struct st_fdma_desc *fdesc;
+	int i;
+
+	fdesc = to_st_fdma_desc(vdesc);
+	for (i = 0; i < fdesc->n_nodes; i++)
+		dma_pool_free(fdesc->fchan->node_pool, fdesc->node[i].desc,
+			      fdesc->node[i].pdesc);
+	kfree(fdesc);
+}
+
+static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan,
+					       int sg_len)
+{
+	struct st_fdma_desc *fdesc;
+	int i;
+
+	fdesc = kzalloc(sizeof(*fdesc) +
+			sizeof(struct st_fdma_sw_node) * sg_len, GFP_NOWAIT);
+	if (!fdesc)
+		return NULL;
+
+	fdesc->fchan = fchan;
+	fdesc->n_nodes = sg_len;
+	for (i = 0; i < sg_len; i++) {
+		fdesc->node[i].desc = dma_pool_alloc(fchan->node_pool,
+				GFP_NOWAIT, &fdesc->node[i].pdesc);
+		if (!fdesc->node[i].desc)
+			goto err;
+	}
+	return fdesc;
+
+err:
+	while (--i >= 0)
+		dma_pool_free(fchan->node_pool, fdesc->node[i].desc,
+			      fdesc->node[i].pdesc);
+	kfree(fdesc);
+	return NULL;
+}
+
+static int st_fdma_alloc_chan_res(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ret;
+
+	/* Create the dma pool for descriptor allocation */
+	fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device),
+					    fchan->fdev->dev,
+					    sizeof(struct st_fdma_hw_node),
+					    __alignof__(struct st_fdma_hw_node),
+					    0);
+
+	if (!fchan->node_pool) {
+		dev_err(fchan->fdev->dev, "unable to allocate desc pool\n");
+		return -ENOMEM;
+	}
+
+
+	ret = rproc_boot(fchan->fdev->rproc);
+	if (ret) {
+		dev_err(fchan->fdev->dev, "rproc_boot failed\n");
+		return ret;
+	}
+
+	dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n",
+		fchan->vchan.chan.chan_id, fchan->cfg.type);
+
+	return 0;
+}
+
+static void st_fdma_free_chan_res(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	unsigned long flags;
+
+	LIST_HEAD(head);
+
+	dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
+		__func__, fchan->vchan.chan.chan_id);
+
+	if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
+		st_fdma_dreq_put(fchan);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	fchan->fdesc = NULL;
+	vchan_get_all_descriptors(&fchan->vchan, &head);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	dma_pool_destroy(fchan->node_pool);
+	fchan->node_pool = NULL;
+	memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
+
+	rproc_shutdown(fchan->fdev->rproc);
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_dma_memcpy(
+	struct dma_chan *chan,	dma_addr_t dst, dma_addr_t src,
+	size_t len, unsigned long flags)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	struct st_fdma_hw_node *hw_node;
+
+	if (!len)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	/* We only require a single descriptor */
+	fdesc = st_fdma_alloc_desc(fchan, 1);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	hw_node = fdesc->node[0].desc;
+	hw_node->next = 0;
+	hw_node->control = NODE_CTRL_REQ_MAP_FREE_RUN;
+	hw_node->control |= NODE_CTRL_SRC_INCR;
+	hw_node->control |= NODE_CTRL_DST_INCR;
+	hw_node->control |= NODE_CTRL_INT_EON;
+	hw_node->nbytes = len;
+	hw_node->saddr = src;
+	hw_node->daddr = dst;
+	hw_node->generic.length = len;
+	hw_node->generic.sstride = 0;
+	hw_node->generic.dstride = 0;
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static int config_reqctrl(struct st_fdma_chan *fchan,
+			  enum dma_transfer_direction direction)
+{
+	u32 maxburst = 0, addr = 0;
+	enum dma_slave_buswidth width;
+	int ch_id = fchan->vchan.chan.chan_id;
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	switch (direction) {
+
+	case DMA_DEV_TO_MEM:
+		fchan->cfg.req_ctrl &= ~REQ_CTRL_WNR;
+		maxburst = fchan->scfg.src_maxburst;
+		width = fchan->scfg.src_addr_width;
+		addr = fchan->scfg.src_addr;
+		break;
+
+	case DMA_MEM_TO_DEV:
+		fchan->cfg.req_ctrl |= REQ_CTRL_WNR;
+		maxburst = fchan->scfg.dst_maxburst;
+		width = fchan->scfg.dst_addr_width;
+		addr = fchan->scfg.dst_addr;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	fchan->cfg.req_ctrl &= ~REQ_CTRL_OPCODE_MASK;
+
+	switch (width) {
+
+	case DMA_SLAVE_BUSWIDTH_1_BYTE:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST1;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_2_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST2;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_4_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST4;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_8_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST8;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	fchan->cfg.req_ctrl &= ~REQ_CTRL_NUM_OPS_MASK;
+	fchan->cfg.req_ctrl |= REQ_CTRL_NUM_OPS(maxburst-1);
+	dreq_write(fchan, fchan->cfg.req_ctrl, FDMA_REQ_CTRL_OFST);
+
+	fchan->cfg.dev_addr = addr;
+	fchan->cfg.dir = direction;
+
+	dev_dbg(fdev->dev, "chan:%d config_reqctrl:%#x req_ctrl:%#lx\n",
+		ch_id, addr, fchan->cfg.req_ctrl);
+
+	return 0;
+}
+
+static void fill_hw_node(struct st_fdma_hw_node *hw_node,
+			struct st_fdma_chan *fchan,
+			enum dma_transfer_direction direction)
+{
+	if (direction == DMA_MEM_TO_DEV) {
+		hw_node->control |= NODE_CTRL_SRC_INCR;
+		hw_node->control |= NODE_CTRL_DST_STATIC;
+		hw_node->daddr = fchan->cfg.dev_addr;
+	} else {
+		hw_node->control |= NODE_CTRL_SRC_STATIC;
+		hw_node->control |= NODE_CTRL_DST_INCR;
+		hw_node->saddr = fchan->cfg.dev_addr;
+	}
+
+	hw_node->generic.sstride = 0;
+	hw_node->generic.dstride = 0;
+}
+
+static struct st_fdma_chan *st_fdma_prep_common(struct dma_chan *chan,
+		size_t len, enum dma_transfer_direction direction)
+{
+	struct st_fdma_chan *fchan;
+
+	if (!chan || !len)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	if (!is_slave_direction(direction)) {
+		dev_err(fchan->fdev->dev, "bad direction?\n");
+		return NULL;
+	}
+
+	return fchan;
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_dma_cyclic(
+		struct dma_chan *chan, dma_addr_t buf_addr, size_t len,
+		size_t period_len, enum dma_transfer_direction direction,
+		unsigned long flags)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	int sg_len, i;
+
+	fchan = st_fdma_prep_common(chan, len, direction);
+	if (!fchan)
+		return NULL;
+
+	if (!period_len)
+		return NULL;
+
+	if (config_reqctrl(fchan, direction)) {
+		dev_err(fchan->fdev->dev, "bad width or direction\n");
+		return NULL;
+	}
+
+	/* the buffer length must be a multiple of period_len */
+	if (len % period_len != 0) {
+		dev_err(fchan->fdev->dev, "len is not multiple of period\n");
+		return NULL;
+	}
+
+	sg_len = len / period_len;
+	fdesc = st_fdma_alloc_desc(fchan, sg_len);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	fdesc->iscyclic = true;
+
+	for (i = 0; i < sg_len; i++) {
+		struct st_fdma_hw_node *hw_node = fdesc->node[i].desc;
+
+		hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
+
+		hw_node->control = NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
+		hw_node->control |= NODE_CTRL_INT_EON;
+
+		fill_hw_node(hw_node, fchan, direction);
+
+		if (direction == DMA_MEM_TO_DEV)
+			hw_node->saddr = buf_addr + (i * period_len);
+		else
+			hw_node->daddr = buf_addr + (i * period_len);
+
+		hw_node->nbytes = period_len;
+		hw_node->generic.length = period_len;
+	}
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_slave_sg(
+		struct dma_chan *chan, struct scatterlist *sgl,
+		unsigned int sg_len, enum dma_transfer_direction direction,
+		unsigned long flags, void *context)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	struct st_fdma_hw_node *hw_node;
+	struct scatterlist *sg;
+	int i;
+
+	fchan = st_fdma_prep_common(chan, sg_len, direction);
+	if (!fchan)
+		return NULL;
+
+	if (!sgl)
+		return NULL;
+
+	fdesc = st_fdma_alloc_desc(fchan, sg_len);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	fdesc->iscyclic = false;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		hw_node = fdesc->node[i].desc;
+
+		hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
+		hw_node->control = NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
+
+		fill_hw_node(hw_node, fchan, direction);
+
+		if (direction == DMA_MEM_TO_DEV)
+			hw_node->saddr = sg_dma_address(sg);
+		else
+			hw_node->daddr = sg_dma_address(sg);
+
+		hw_node->nbytes = sg_dma_len(sg);
+		hw_node->generic.length = sg_dma_len(sg);
+	}
+
+	/* interrupt at end of last node */
+	hw_node->control |= NODE_CTRL_INT_EON;
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static size_t st_fdma_desc_residue(struct st_fdma_chan *fchan,
+				   struct virt_dma_desc *vdesc,
+				   bool in_progress)
+{
+	struct st_fdma_desc *fdesc = fchan->fdesc;
+	size_t residue = 0;
+	dma_addr_t cur_addr = 0;
+	int i;
+
+	if (in_progress) {
+		cur_addr = fchan_read(fchan, FDMA_CH_CMD_OFST);
+		cur_addr &= FDMA_CH_CMD_DATA_MASK;
+	}
+
+	for (i = fchan->fdesc->n_nodes - 1 ; i >= 0; i--) {
+		if (cur_addr == fdesc->node[i].pdesc) {
+			residue += fnode_read(fchan, FDMA_CNTN_OFST);
+			break;
+		}
+		residue += fdesc->node[i].desc->nbytes;
+	}
+
+	return residue;
+}
+
+static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
+					 dma_cookie_t cookie,
+					 struct dma_tx_state *txstate)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	struct virt_dma_desc *vd;
+	enum dma_status ret;
+	unsigned long flags;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_COMPLETE)
+		return ret;
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	vd = vchan_find_desc(&fchan->vchan, cookie);
+	if (fchan->fdesc && cookie == fchan->fdesc->vdesc.tx.cookie)
+		txstate->residue = st_fdma_desc_residue(fchan, vd, true);
+	else if (vd)
+		txstate->residue = st_fdma_desc_residue(fchan, vd, false);
+	else
+		txstate->residue = 0;
+
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return ret;
+}
+
+static void st_fdma_issue_pending(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+
+	if (vchan_issue_pending(&fchan->vchan) && !fchan->fdesc)
+		st_fdma_xfer_desc(fchan);
+
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+}
+
+static int st_fdma_pause(struct dma_chan *chan)
+{
+	unsigned long flags;
+	LIST_HEAD(head);
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+	unsigned long cmd = FDMA_CMD_PAUSE(ch_id);
+
+	dev_dbg(fchan->fdev->dev, "pause chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	if (fchan->fdesc)
+		fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return 0;
+}
+
+static int st_fdma_resume(struct dma_chan *chan)
+{
+	unsigned long flags;
+	unsigned long val;
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+
+	dev_dbg(fchan->fdev->dev, "resume chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	if (fchan->fdesc) {
+		val = fchan_read(fchan, FDMA_CH_CMD_OFST);
+		val &= FDMA_CH_CMD_DATA_MASK;
+		fchan_write(fchan, val, FDMA_CH_CMD_OFST);
+	}
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return 0;
+}
+
+static int st_fdma_terminate_all(struct dma_chan *chan)
+{
+	unsigned long flags;
+	LIST_HEAD(head);
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+	unsigned long cmd = FDMA_CMD_PAUSE(ch_id);
+
+	dev_dbg(fchan->fdev->dev, "terminate chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST);
+	fchan->fdesc = NULL;
+	vchan_get_all_descriptors(&fchan->vchan, &head);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+	vchan_dma_desc_free_list(&fchan->vchan, &head);
+
+	return 0;
+}
+
+static int st_fdma_slave_config(struct dma_chan *chan,
+				struct dma_slave_config *slave_cfg)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+
+	memcpy(&fchan->scfg, slave_cfg, sizeof(fchan->scfg));
+	return 0;
+}
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_11 = {
+	.name = "STiH407",
+	.id = 0,
+};
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_12 = {
+	.name = "STiH407",
+	.id = 1,
+};
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_13 = {
+	.name = "STiH407",
+	.id = 2,
+};
+
+static const struct of_device_id st_fdma_match[] = {
+	{ .compatible = "st,stih407-fdma-mpe31-11"
+	  , .data = &fdma_mpe31_stih407_11 },
+	{ .compatible = "st,stih407-fdma-mpe31-12"
+	  , .data = &fdma_mpe31_stih407_12 },
+	{ .compatible = "st,stih407-fdma-mpe31-13"
+	  , .data = &fdma_mpe31_stih407_13 },
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_fdma_match);
+
+static int st_fdma_parse_dt(struct platform_device *pdev,
+			const struct st_fdma_driverdata *drvdata,
+			struct st_fdma_dev *fdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	if (!np)
+		goto err;
+
+	ret = of_property_read_u32(np, "dma-channels", &fdev->nr_channels);
+	if (ret)
+		goto err;
+
+	snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf",
+		drvdata->name, drvdata->id);
+
+err:
+	return ret;
+}
+#define FDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+static int st_fdma_probe(struct platform_device *pdev)
+{
+	struct st_fdma_dev *fdev;
+	const struct of_device_id *match;
+	struct device_node *np = pdev->dev.of_node;
+	const struct st_fdma_driverdata *drvdata;
+	int ret, i;
+
+	match = of_match_device((st_fdma_match), &pdev->dev);
+	if (!match || !match->data) {
+		dev_err(&pdev->dev, "No device match found\n");
+		return -ENODEV;
+	}
+
+	drvdata = match->data;
+
+	fdev = devm_kzalloc(&pdev->dev, sizeof(*fdev), GFP_KERNEL);
+	if (!fdev)
+		return -ENOMEM;
+
+	ret = st_fdma_parse_dt(pdev, drvdata, fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to find platform data\n");
+		goto err;
+	}
+
+	fdev->chans = devm_kzalloc(&pdev->dev,
+				   fdev->nr_channels
+				   * sizeof(struct st_fdma_chan), GFP_KERNEL);
+	if (!fdev->chans)
+		return -ENOMEM;
+
+	fdev->dev = &pdev->dev;
+	fdev->drvdata = drvdata;
+	platform_set_drvdata(pdev, fdev);
+
+	fdev->irq = platform_get_irq(pdev, 0);
+	if (fdev->irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource\n");
+		return -EINVAL;
+	}
+
+	ret = devm_request_irq(&pdev->dev, fdev->irq, st_fdma_irq_handler, 0,
+			       dev_name(&pdev->dev), fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request irq\n");
+		goto err;
+	}
+
+	fdev->rproc = xp70_rproc_alloc(pdev, fdev->fw_name);
+	if (!fdev->rproc) {
+		dev_err(&pdev->dev, "xp70_rproc_init failed\n");
+		ret = PTR_ERR(fdev->rproc);
+		goto err;
+	}
+
+	fdev->xp70_rproc = fdev->rproc->priv;
+
+	/* Initialise list of FDMA channels */
+	INIT_LIST_HEAD(&fdev->dma_device.channels);
+	for (i = 0; i < fdev->nr_channels; i++) {
+		struct st_fdma_chan *fchan = &fdev->chans[i];
+
+		fchan->fdev = fdev;
+		fchan->vchan.desc_free = st_fdma_free_desc;
+		vchan_init(&fchan->vchan, &fdev->dma_device);
+	}
+
+	/* Initialise the FDMA dreq (reserve 0 & 31 for FDMA use) */
+	fdev->dreq_mask = BIT(0) | BIT(31);
+
+	dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);
+	dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
+	dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);
+
+	fdev->dma_device.dev = &pdev->dev;
+	fdev->dma_device.device_alloc_chan_resources = st_fdma_alloc_chan_res;
+	fdev->dma_device.device_free_chan_resources = st_fdma_free_chan_res;
+	fdev->dma_device.device_prep_dma_cyclic	= st_fdma_prep_dma_cyclic;
+	fdev->dma_device.device_prep_slave_sg = st_fdma_prep_slave_sg;
+	fdev->dma_device.device_prep_dma_memcpy = st_fdma_prep_dma_memcpy;
+	fdev->dma_device.device_tx_status = st_fdma_tx_status;
+	fdev->dma_device.device_issue_pending = st_fdma_issue_pending;
+	fdev->dma_device.device_terminate_all = st_fdma_terminate_all;
+	fdev->dma_device.device_config = st_fdma_slave_config;
+	fdev->dma_device.device_pause = st_fdma_pause;
+	fdev->dma_device.device_resume = st_fdma_resume;
+
+	fdev->dma_device.src_addr_widths = FDMA_DMA_BUSWIDTHS;
+	fdev->dma_device.dst_addr_widths = FDMA_DMA_BUSWIDTHS;
+	fdev->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	fdev->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+
+	ret = dma_async_device_register(&fdev->dma_device);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register DMA device\n");
+		goto err_rproc;
+	}
+
+	ret = of_dma_controller_register(np, st_fdma_of_xlate, fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register controller\n");
+		goto err_dma_dev;
+	}
+
+	dev_info(&pdev->dev, "ST FDMA engine driver, irq:%d\n", fdev->irq);
+
+	return 0;
+
+err_dma_dev:
+	dma_async_device_unregister(&fdev->dma_device);
+err_rproc:
+	xp70_rproc_put(fdev->xp70_rproc);
+err:
+	return ret;
+}
+
+static int st_fdma_remove(struct platform_device *pdev)
+{
+	struct st_fdma_dev *fdev = platform_get_drvdata(pdev);
+
+	devm_free_irq(&pdev->dev, fdev->irq, fdev);
+	xp70_rproc_put(fdev->xp70_rproc);
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&fdev->dma_device);
+
+	return 0;
+}
+
+static struct platform_driver st_fdma_platform_driver = {
+	.driver = {
+		.name = "st-fdma",
+		.of_match_table = st_fdma_match,
+	},
+	.probe = st_fdma_probe,
+	.remove = st_fdma_remove,
+};
+module_platform_driver(st_fdma_platform_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
+MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>");
+MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
-- 
1.9.1

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

* [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: devicetree, linux-remoteproc, peter.griffin, dmaengine,
	lee.jones, Ludovic Barre

This patch adds support for the Flexible Direct Memory Access (FDMA) core
driver. The FDMA is a slim core CPU with a dedicated firmware.
It is a general purpose DMA controller capable of supporting 16
independent DMA channels. Data moves maybe from memory to memory
or between memory and paced latency critical real time targets and it
is found on al STi based chipsets.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/dma/Kconfig   |  12 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/st_fdma.c | 882 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 895 insertions(+)
 create mode 100644 drivers/dma/st_fdma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index d96d87c..a65b8b3 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -527,6 +527,18 @@ config ZX_DMA
 	help
 	  Support the DMA engine for ZTE ZX296702 platform devices.
 
+config ST_FDMA
+	tristate "ST FDMA dmaengine support"
+	depends on ARCH_STI || COMPILE_TEST
+        depends on ST_XP70_REMOTEPROC
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	help
+	  Enable support for ST FDMA controller.
+	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
+
+	  Say Y here if you have such a chipset.
+	  If unsure, say N.
 
 # driver files
 source "drivers/dma/bestcomm/Kconfig"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 6084127..b81ca99 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
 obj-$(CONFIG_TI_EDMA) += edma.o
 obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx296702_dma.o
+obj-$(CONFIG_ST_FDMA) += st_fdma.o
 
 obj-y += qcom/
 obj-y += xilinx/
diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
new file mode 100644
index 0000000..34496b0
--- /dev/null
+++ b/drivers/dma/st_fdma.c
@@ -0,0 +1,882 @@
+/*
+ * st_fdma.c
+ *
+ * Copyright (C) 2014 STMicroelectronics
+ * Author: Ludovic Barre <Ludovic.barre@st.com>
+ *	   Peter Griffin <peter.griffin@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
+#include <linux/firmware.h>
+#include <linux/elf.h>
+#include <linux/atomic.h>
+#include <linux/remoteproc.h>
+#include <linux/io.h>
+
+#include "st_fdma.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+static inline struct st_fdma_chan *to_st_fdma_chan(struct dma_chan *c)
+{
+	return container_of(c, struct st_fdma_chan, vchan.chan);
+}
+
+static struct st_fdma_desc *to_st_fdma_desc(struct virt_dma_desc *vd)
+{
+	return container_of(vd, struct st_fdma_desc, vdesc);
+}
+
+static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
+{
+	struct st_fdma_dev *fdev = fchan->fdev;
+	u32 req_line_cfg = fchan->cfg.req_line;
+	u32 dreq_line;
+	int try = 0;
+
+	/*
+	 * dreq_mask is shared for n channels of fdma, so all accesses must be
+	 * atomic. if the dreq_mask it change between ffz ant set_bit,
+	 * we retry
+	 */
+	do {
+		if (fdev->dreq_mask == ~0L) {
+			dev_err(fdev->dev, "No req lines available\n");
+			return -EINVAL;
+		}
+
+		if (try || req_line_cfg >= ST_FDMA_NR_DREQS) {
+			dev_err(fdev->dev, "Invalid or used req line\n");
+			return -EINVAL;
+		} else {
+			dreq_line = req_line_cfg;
+		}
+
+		try++;
+	} while (test_and_set_bit(dreq_line, &fdev->dreq_mask));
+
+	dev_dbg(fdev->dev, "get dreq_line:%d mask:%#lx\n",
+		dreq_line, fdev->dreq_mask);
+
+	return dreq_line;
+}
+
+static void st_fdma_dreq_put(struct st_fdma_chan *fchan)
+{
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line);
+	clear_bit(fchan->dreq_line, &fdev->dreq_mask);
+}
+
+static void st_fdma_xfer_desc(struct st_fdma_chan *fchan)
+{
+	struct virt_dma_desc *vdesc;
+	unsigned long nbytes, ch_cmd, cmd;
+
+	vdesc = vchan_next_desc(&fchan->vchan);
+	if (!vdesc)
+		return;
+
+	fchan->fdesc = to_st_fdma_desc(vdesc);
+	nbytes = fchan->fdesc->node[0].desc->nbytes;
+	cmd = FDMA_CMD_START(fchan->vchan.chan.chan_id);
+	ch_cmd = fchan->fdesc->node[0].pdesc | FDMA_CH_CMD_STA_START;
+
+	/* start the channel for the descriptor */
+	fnode_write(fchan, nbytes, FDMA_CNTN_OFST);
+	fchan_write(fchan, ch_cmd, FDMA_CH_CMD_OFST);
+	writel(cmd,
+		fchan->fdev->xp70_rproc->peri + FDMA_CMD_SET_OFST);
+
+	dev_dbg(fchan->fdev->dev, "start chan:%d\n", fchan->vchan.chan.chan_id);
+}
+
+static void st_fdma_ch_sta_update(struct st_fdma_chan *fchan,
+				  unsigned long int_sta)
+{
+	unsigned long ch_sta, ch_err;
+	int ch_id = fchan->vchan.chan.chan_id;
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	ch_sta = fchan_read(fchan, FDMA_CH_CMD_OFST);
+	ch_err = ch_sta & FDMA_CH_CMD_ERR_MASK;
+	ch_sta &= FDMA_CH_CMD_STA_MASK;
+
+	if (int_sta & FDMA_INT_STA_ERR) {
+		dev_warn(fdev->dev, "chan:%d, error:%ld\n", ch_id, ch_err);
+		fchan->status = DMA_ERROR;
+		return;
+	}
+
+	switch (ch_sta) {
+	case FDMA_CH_CMD_STA_PAUSED:
+		fchan->status = DMA_PAUSED;
+		break;
+	case FDMA_CH_CMD_STA_RUNNING:
+		fchan->status = DMA_IN_PROGRESS;
+		break;
+	}
+}
+
+static irqreturn_t st_fdma_irq_handler(int irq, void *dev_id)
+{
+	struct st_fdma_dev *fdev = dev_id;
+	irqreturn_t ret = IRQ_NONE;
+	struct st_fdma_chan *fchan = &fdev->chans[0];
+	unsigned long int_sta, clr;
+
+	int_sta = fdma_read(fdev, FDMA_INT_STA_OFST);
+	clr = int_sta;
+
+	for (; int_sta != 0 ; int_sta >>= 2, fchan++) {
+		if (!(int_sta & (FDMA_INT_STA_CH | FDMA_INT_STA_ERR)))
+			continue;
+
+		spin_lock(&fchan->vchan.lock);
+		st_fdma_ch_sta_update(fchan, int_sta);
+
+		if (fchan->fdesc) {
+			if (!fchan->fdesc->iscyclic) {
+				list_del(&fchan->fdesc->vdesc.node);
+				vchan_cookie_complete(&fchan->fdesc->vdesc);
+				fchan->fdesc = NULL;
+				fchan->status = DMA_COMPLETE;
+			} else {
+				vchan_cyclic_callback(&fchan->fdesc->vdesc);
+			}
+
+			/* Start the next descriptor (if available) */
+			if (!fchan->fdesc)
+				st_fdma_xfer_desc(fchan);
+		}
+
+		spin_unlock(&fchan->vchan.lock);
+		ret = IRQ_HANDLED;
+	}
+
+	fdma_write(fdev, clr, FDMA_INT_CLR_OFST);
+
+	return ret;
+}
+
+static struct dma_chan *st_fdma_of_xlate(struct of_phandle_args *dma_spec,
+					 struct of_dma *ofdma)
+{
+	struct st_fdma_dev *fdev = ofdma->of_dma_data;
+	struct dma_chan *chan;
+	struct st_fdma_chan *fchan;
+
+	if (dma_spec->args_count < 1)
+		return NULL;
+
+	chan = dma_get_any_slave_channel(&fdev->dma_device);
+	if (!chan)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	if (fchan->fdev->dma_device.dev->of_node != dma_spec->np)
+		return NULL;
+
+	fchan->cfg.of_node = dma_spec->np;
+	fchan->cfg.req_line = dma_spec->args[0];
+	fchan->cfg.req_ctrl = 0;
+	fchan->cfg.type = ST_FDMA_TYPE_FREE_RUN;
+
+	if (dma_spec->args_count > 1)
+		fchan->cfg.req_ctrl = dma_spec->args[1] & REQ_CTRL_CFG_MASK;
+
+	if (dma_spec->args_count > 2)
+		fchan->cfg.type = dma_spec->args[2];
+
+	if (fchan->cfg.type == ST_FDMA_TYPE_FREE_RUN) {
+		fchan->dreq_line = 0;
+	} else {
+		fchan->dreq_line = st_fdma_dreq_get(fchan);
+		if (IS_ERR_VALUE(fchan->dreq_line))
+			return NULL;
+	}
+
+	dev_dbg(fdev->dev, "xlate req_line:%d type:%d req_ctrl:%#lx\n",
+		fchan->cfg.req_line, fchan->cfg.type, fchan->cfg.req_ctrl);
+
+	return chan;
+}
+
+static void st_fdma_free_desc(struct virt_dma_desc *vdesc)
+{
+	struct st_fdma_desc *fdesc;
+	int i;
+
+	fdesc = to_st_fdma_desc(vdesc);
+	for (i = 0; i < fdesc->n_nodes; i++)
+		dma_pool_free(fdesc->fchan->node_pool, fdesc->node[i].desc,
+			      fdesc->node[i].pdesc);
+	kfree(fdesc);
+}
+
+static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan,
+					       int sg_len)
+{
+	struct st_fdma_desc *fdesc;
+	int i;
+
+	fdesc = kzalloc(sizeof(*fdesc) +
+			sizeof(struct st_fdma_sw_node) * sg_len, GFP_NOWAIT);
+	if (!fdesc)
+		return NULL;
+
+	fdesc->fchan = fchan;
+	fdesc->n_nodes = sg_len;
+	for (i = 0; i < sg_len; i++) {
+		fdesc->node[i].desc = dma_pool_alloc(fchan->node_pool,
+				GFP_NOWAIT, &fdesc->node[i].pdesc);
+		if (!fdesc->node[i].desc)
+			goto err;
+	}
+	return fdesc;
+
+err:
+	while (--i >= 0)
+		dma_pool_free(fchan->node_pool, fdesc->node[i].desc,
+			      fdesc->node[i].pdesc);
+	kfree(fdesc);
+	return NULL;
+}
+
+static int st_fdma_alloc_chan_res(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ret;
+
+	/* Create the dma pool for descriptor allocation */
+	fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device),
+					    fchan->fdev->dev,
+					    sizeof(struct st_fdma_hw_node),
+					    __alignof__(struct st_fdma_hw_node),
+					    0);
+
+	if (!fchan->node_pool) {
+		dev_err(fchan->fdev->dev, "unable to allocate desc pool\n");
+		return -ENOMEM;
+	}
+
+
+	ret = rproc_boot(fchan->fdev->rproc);
+	if (ret) {
+		dev_err(fchan->fdev->dev, "rproc_boot failed\n");
+		return ret;
+	}
+
+	dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n",
+		fchan->vchan.chan.chan_id, fchan->cfg.type);
+
+	return 0;
+}
+
+static void st_fdma_free_chan_res(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	unsigned long flags;
+
+	LIST_HEAD(head);
+
+	dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
+		__func__, fchan->vchan.chan.chan_id);
+
+	if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
+		st_fdma_dreq_put(fchan);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	fchan->fdesc = NULL;
+	vchan_get_all_descriptors(&fchan->vchan, &head);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	dma_pool_destroy(fchan->node_pool);
+	fchan->node_pool = NULL;
+	memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
+
+	rproc_shutdown(fchan->fdev->rproc);
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_dma_memcpy(
+	struct dma_chan *chan,	dma_addr_t dst, dma_addr_t src,
+	size_t len, unsigned long flags)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	struct st_fdma_hw_node *hw_node;
+
+	if (!len)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	/* We only require a single descriptor */
+	fdesc = st_fdma_alloc_desc(fchan, 1);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	hw_node = fdesc->node[0].desc;
+	hw_node->next = 0;
+	hw_node->control = NODE_CTRL_REQ_MAP_FREE_RUN;
+	hw_node->control |= NODE_CTRL_SRC_INCR;
+	hw_node->control |= NODE_CTRL_DST_INCR;
+	hw_node->control |= NODE_CTRL_INT_EON;
+	hw_node->nbytes = len;
+	hw_node->saddr = src;
+	hw_node->daddr = dst;
+	hw_node->generic.length = len;
+	hw_node->generic.sstride = 0;
+	hw_node->generic.dstride = 0;
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static int config_reqctrl(struct st_fdma_chan *fchan,
+			  enum dma_transfer_direction direction)
+{
+	u32 maxburst = 0, addr = 0;
+	enum dma_slave_buswidth width;
+	int ch_id = fchan->vchan.chan.chan_id;
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	switch (direction) {
+
+	case DMA_DEV_TO_MEM:
+		fchan->cfg.req_ctrl &= ~REQ_CTRL_WNR;
+		maxburst = fchan->scfg.src_maxburst;
+		width = fchan->scfg.src_addr_width;
+		addr = fchan->scfg.src_addr;
+		break;
+
+	case DMA_MEM_TO_DEV:
+		fchan->cfg.req_ctrl |= REQ_CTRL_WNR;
+		maxburst = fchan->scfg.dst_maxburst;
+		width = fchan->scfg.dst_addr_width;
+		addr = fchan->scfg.dst_addr;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	fchan->cfg.req_ctrl &= ~REQ_CTRL_OPCODE_MASK;
+
+	switch (width) {
+
+	case DMA_SLAVE_BUSWIDTH_1_BYTE:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST1;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_2_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST2;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_4_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST4;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_8_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST8;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	fchan->cfg.req_ctrl &= ~REQ_CTRL_NUM_OPS_MASK;
+	fchan->cfg.req_ctrl |= REQ_CTRL_NUM_OPS(maxburst-1);
+	dreq_write(fchan, fchan->cfg.req_ctrl, FDMA_REQ_CTRL_OFST);
+
+	fchan->cfg.dev_addr = addr;
+	fchan->cfg.dir = direction;
+
+	dev_dbg(fdev->dev, "chan:%d config_reqctrl:%#x req_ctrl:%#lx\n",
+		ch_id, addr, fchan->cfg.req_ctrl);
+
+	return 0;
+}
+
+static void fill_hw_node(struct st_fdma_hw_node *hw_node,
+			struct st_fdma_chan *fchan,
+			enum dma_transfer_direction direction)
+{
+	if (direction == DMA_MEM_TO_DEV) {
+		hw_node->control |= NODE_CTRL_SRC_INCR;
+		hw_node->control |= NODE_CTRL_DST_STATIC;
+		hw_node->daddr = fchan->cfg.dev_addr;
+	} else {
+		hw_node->control |= NODE_CTRL_SRC_STATIC;
+		hw_node->control |= NODE_CTRL_DST_INCR;
+		hw_node->saddr = fchan->cfg.dev_addr;
+	}
+
+	hw_node->generic.sstride = 0;
+	hw_node->generic.dstride = 0;
+}
+
+static struct st_fdma_chan *st_fdma_prep_common(struct dma_chan *chan,
+		size_t len, enum dma_transfer_direction direction)
+{
+	struct st_fdma_chan *fchan;
+
+	if (!chan || !len)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	if (!is_slave_direction(direction)) {
+		dev_err(fchan->fdev->dev, "bad direction?\n");
+		return NULL;
+	}
+
+	return fchan;
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_dma_cyclic(
+		struct dma_chan *chan, dma_addr_t buf_addr, size_t len,
+		size_t period_len, enum dma_transfer_direction direction,
+		unsigned long flags)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	int sg_len, i;
+
+	fchan = st_fdma_prep_common(chan, len, direction);
+	if (!fchan)
+		return NULL;
+
+	if (!period_len)
+		return NULL;
+
+	if (config_reqctrl(fchan, direction)) {
+		dev_err(fchan->fdev->dev, "bad width or direction\n");
+		return NULL;
+	}
+
+	/* the buffer length must be a multiple of period_len */
+	if (len % period_len != 0) {
+		dev_err(fchan->fdev->dev, "len is not multiple of period\n");
+		return NULL;
+	}
+
+	sg_len = len / period_len;
+	fdesc = st_fdma_alloc_desc(fchan, sg_len);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	fdesc->iscyclic = true;
+
+	for (i = 0; i < sg_len; i++) {
+		struct st_fdma_hw_node *hw_node = fdesc->node[i].desc;
+
+		hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
+
+		hw_node->control = NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
+		hw_node->control |= NODE_CTRL_INT_EON;
+
+		fill_hw_node(hw_node, fchan, direction);
+
+		if (direction == DMA_MEM_TO_DEV)
+			hw_node->saddr = buf_addr + (i * period_len);
+		else
+			hw_node->daddr = buf_addr + (i * period_len);
+
+		hw_node->nbytes = period_len;
+		hw_node->generic.length = period_len;
+	}
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_slave_sg(
+		struct dma_chan *chan, struct scatterlist *sgl,
+		unsigned int sg_len, enum dma_transfer_direction direction,
+		unsigned long flags, void *context)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	struct st_fdma_hw_node *hw_node;
+	struct scatterlist *sg;
+	int i;
+
+	fchan = st_fdma_prep_common(chan, sg_len, direction);
+	if (!fchan)
+		return NULL;
+
+	if (!sgl)
+		return NULL;
+
+	fdesc = st_fdma_alloc_desc(fchan, sg_len);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	fdesc->iscyclic = false;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		hw_node = fdesc->node[i].desc;
+
+		hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
+		hw_node->control = NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
+
+		fill_hw_node(hw_node, fchan, direction);
+
+		if (direction == DMA_MEM_TO_DEV)
+			hw_node->saddr = sg_dma_address(sg);
+		else
+			hw_node->daddr = sg_dma_address(sg);
+
+		hw_node->nbytes = sg_dma_len(sg);
+		hw_node->generic.length = sg_dma_len(sg);
+	}
+
+	/* interrupt at end of last node */
+	hw_node->control |= NODE_CTRL_INT_EON;
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static size_t st_fdma_desc_residue(struct st_fdma_chan *fchan,
+				   struct virt_dma_desc *vdesc,
+				   bool in_progress)
+{
+	struct st_fdma_desc *fdesc = fchan->fdesc;
+	size_t residue = 0;
+	dma_addr_t cur_addr = 0;
+	int i;
+
+	if (in_progress) {
+		cur_addr = fchan_read(fchan, FDMA_CH_CMD_OFST);
+		cur_addr &= FDMA_CH_CMD_DATA_MASK;
+	}
+
+	for (i = fchan->fdesc->n_nodes - 1 ; i >= 0; i--) {
+		if (cur_addr == fdesc->node[i].pdesc) {
+			residue += fnode_read(fchan, FDMA_CNTN_OFST);
+			break;
+		}
+		residue += fdesc->node[i].desc->nbytes;
+	}
+
+	return residue;
+}
+
+static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
+					 dma_cookie_t cookie,
+					 struct dma_tx_state *txstate)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	struct virt_dma_desc *vd;
+	enum dma_status ret;
+	unsigned long flags;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_COMPLETE)
+		return ret;
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	vd = vchan_find_desc(&fchan->vchan, cookie);
+	if (fchan->fdesc && cookie == fchan->fdesc->vdesc.tx.cookie)
+		txstate->residue = st_fdma_desc_residue(fchan, vd, true);
+	else if (vd)
+		txstate->residue = st_fdma_desc_residue(fchan, vd, false);
+	else
+		txstate->residue = 0;
+
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return ret;
+}
+
+static void st_fdma_issue_pending(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+
+	if (vchan_issue_pending(&fchan->vchan) && !fchan->fdesc)
+		st_fdma_xfer_desc(fchan);
+
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+}
+
+static int st_fdma_pause(struct dma_chan *chan)
+{
+	unsigned long flags;
+	LIST_HEAD(head);
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+	unsigned long cmd = FDMA_CMD_PAUSE(ch_id);
+
+	dev_dbg(fchan->fdev->dev, "pause chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	if (fchan->fdesc)
+		fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return 0;
+}
+
+static int st_fdma_resume(struct dma_chan *chan)
+{
+	unsigned long flags;
+	unsigned long val;
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+
+	dev_dbg(fchan->fdev->dev, "resume chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	if (fchan->fdesc) {
+		val = fchan_read(fchan, FDMA_CH_CMD_OFST);
+		val &= FDMA_CH_CMD_DATA_MASK;
+		fchan_write(fchan, val, FDMA_CH_CMD_OFST);
+	}
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return 0;
+}
+
+static int st_fdma_terminate_all(struct dma_chan *chan)
+{
+	unsigned long flags;
+	LIST_HEAD(head);
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+	unsigned long cmd = FDMA_CMD_PAUSE(ch_id);
+
+	dev_dbg(fchan->fdev->dev, "terminate chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST);
+	fchan->fdesc = NULL;
+	vchan_get_all_descriptors(&fchan->vchan, &head);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+	vchan_dma_desc_free_list(&fchan->vchan, &head);
+
+	return 0;
+}
+
+static int st_fdma_slave_config(struct dma_chan *chan,
+				struct dma_slave_config *slave_cfg)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+
+	memcpy(&fchan->scfg, slave_cfg, sizeof(fchan->scfg));
+	return 0;
+}
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_11 = {
+	.name = "STiH407",
+	.id = 0,
+};
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_12 = {
+	.name = "STiH407",
+	.id = 1,
+};
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_13 = {
+	.name = "STiH407",
+	.id = 2,
+};
+
+static const struct of_device_id st_fdma_match[] = {
+	{ .compatible = "st,stih407-fdma-mpe31-11"
+	  , .data = &fdma_mpe31_stih407_11 },
+	{ .compatible = "st,stih407-fdma-mpe31-12"
+	  , .data = &fdma_mpe31_stih407_12 },
+	{ .compatible = "st,stih407-fdma-mpe31-13"
+	  , .data = &fdma_mpe31_stih407_13 },
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_fdma_match);
+
+static int st_fdma_parse_dt(struct platform_device *pdev,
+			const struct st_fdma_driverdata *drvdata,
+			struct st_fdma_dev *fdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	if (!np)
+		goto err;
+
+	ret = of_property_read_u32(np, "dma-channels", &fdev->nr_channels);
+	if (ret)
+		goto err;
+
+	snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf",
+		drvdata->name, drvdata->id);
+
+err:
+	return ret;
+}
+#define FDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+static int st_fdma_probe(struct platform_device *pdev)
+{
+	struct st_fdma_dev *fdev;
+	const struct of_device_id *match;
+	struct device_node *np = pdev->dev.of_node;
+	const struct st_fdma_driverdata *drvdata;
+	int ret, i;
+
+	match = of_match_device((st_fdma_match), &pdev->dev);
+	if (!match || !match->data) {
+		dev_err(&pdev->dev, "No device match found\n");
+		return -ENODEV;
+	}
+
+	drvdata = match->data;
+
+	fdev = devm_kzalloc(&pdev->dev, sizeof(*fdev), GFP_KERNEL);
+	if (!fdev)
+		return -ENOMEM;
+
+	ret = st_fdma_parse_dt(pdev, drvdata, fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to find platform data\n");
+		goto err;
+	}
+
+	fdev->chans = devm_kzalloc(&pdev->dev,
+				   fdev->nr_channels
+				   * sizeof(struct st_fdma_chan), GFP_KERNEL);
+	if (!fdev->chans)
+		return -ENOMEM;
+
+	fdev->dev = &pdev->dev;
+	fdev->drvdata = drvdata;
+	platform_set_drvdata(pdev, fdev);
+
+	fdev->irq = platform_get_irq(pdev, 0);
+	if (fdev->irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource\n");
+		return -EINVAL;
+	}
+
+	ret = devm_request_irq(&pdev->dev, fdev->irq, st_fdma_irq_handler, 0,
+			       dev_name(&pdev->dev), fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request irq\n");
+		goto err;
+	}
+
+	fdev->rproc = xp70_rproc_alloc(pdev, fdev->fw_name);
+	if (!fdev->rproc) {
+		dev_err(&pdev->dev, "xp70_rproc_init failed\n");
+		ret = PTR_ERR(fdev->rproc);
+		goto err;
+	}
+
+	fdev->xp70_rproc = fdev->rproc->priv;
+
+	/* Initialise list of FDMA channels */
+	INIT_LIST_HEAD(&fdev->dma_device.channels);
+	for (i = 0; i < fdev->nr_channels; i++) {
+		struct st_fdma_chan *fchan = &fdev->chans[i];
+
+		fchan->fdev = fdev;
+		fchan->vchan.desc_free = st_fdma_free_desc;
+		vchan_init(&fchan->vchan, &fdev->dma_device);
+	}
+
+	/* Initialise the FDMA dreq (reserve 0 & 31 for FDMA use) */
+	fdev->dreq_mask = BIT(0) | BIT(31);
+
+	dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);
+	dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
+	dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);
+
+	fdev->dma_device.dev = &pdev->dev;
+	fdev->dma_device.device_alloc_chan_resources = st_fdma_alloc_chan_res;
+	fdev->dma_device.device_free_chan_resources = st_fdma_free_chan_res;
+	fdev->dma_device.device_prep_dma_cyclic	= st_fdma_prep_dma_cyclic;
+	fdev->dma_device.device_prep_slave_sg = st_fdma_prep_slave_sg;
+	fdev->dma_device.device_prep_dma_memcpy = st_fdma_prep_dma_memcpy;
+	fdev->dma_device.device_tx_status = st_fdma_tx_status;
+	fdev->dma_device.device_issue_pending = st_fdma_issue_pending;
+	fdev->dma_device.device_terminate_all = st_fdma_terminate_all;
+	fdev->dma_device.device_config = st_fdma_slave_config;
+	fdev->dma_device.device_pause = st_fdma_pause;
+	fdev->dma_device.device_resume = st_fdma_resume;
+
+	fdev->dma_device.src_addr_widths = FDMA_DMA_BUSWIDTHS;
+	fdev->dma_device.dst_addr_widths = FDMA_DMA_BUSWIDTHS;
+	fdev->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	fdev->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+
+	ret = dma_async_device_register(&fdev->dma_device);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register DMA device\n");
+		goto err_rproc;
+	}
+
+	ret = of_dma_controller_register(np, st_fdma_of_xlate, fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register controller\n");
+		goto err_dma_dev;
+	}
+
+	dev_info(&pdev->dev, "ST FDMA engine driver, irq:%d\n", fdev->irq);
+
+	return 0;
+
+err_dma_dev:
+	dma_async_device_unregister(&fdev->dma_device);
+err_rproc:
+	xp70_rproc_put(fdev->xp70_rproc);
+err:
+	return ret;
+}
+
+static int st_fdma_remove(struct platform_device *pdev)
+{
+	struct st_fdma_dev *fdev = platform_get_drvdata(pdev);
+
+	devm_free_irq(&pdev->dev, fdev->irq, fdev);
+	xp70_rproc_put(fdev->xp70_rproc);
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&fdev->dma_device);
+
+	return 0;
+}
+
+static struct platform_driver st_fdma_platform_driver = {
+	.driver = {
+		.name = "st-fdma",
+		.of_match_table = st_fdma_match,
+	},
+	.probe = st_fdma_probe,
+	.remove = st_fdma_remove,
+};
+module_platform_driver(st_fdma_platform_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
+MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>");
+MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
-- 
1.9.1

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

* [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for the Flexible Direct Memory Access (FDMA) core
driver. The FDMA is a slim core CPU with a dedicated firmware.
It is a general purpose DMA controller capable of supporting 16
independent DMA channels. Data moves maybe from memory to memory
or between memory and paced latency critical real time targets and it
is found on al STi based chipsets.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/dma/Kconfig   |  12 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/st_fdma.c | 882 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 895 insertions(+)
 create mode 100644 drivers/dma/st_fdma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index d96d87c..a65b8b3 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -527,6 +527,18 @@ config ZX_DMA
 	help
 	  Support the DMA engine for ZTE ZX296702 platform devices.
 
+config ST_FDMA
+	tristate "ST FDMA dmaengine support"
+	depends on ARCH_STI || COMPILE_TEST
+        depends on ST_XP70_REMOTEPROC
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	help
+	  Enable support for ST FDMA controller.
+	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
+
+	  Say Y here if you have such a chipset.
+	  If unsure, say N.
 
 # driver files
 source "drivers/dma/bestcomm/Kconfig"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 6084127..b81ca99 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
 obj-$(CONFIG_TI_EDMA) += edma.o
 obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx296702_dma.o
+obj-$(CONFIG_ST_FDMA) += st_fdma.o
 
 obj-y += qcom/
 obj-y += xilinx/
diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
new file mode 100644
index 0000000..34496b0
--- /dev/null
+++ b/drivers/dma/st_fdma.c
@@ -0,0 +1,882 @@
+/*
+ * st_fdma.c
+ *
+ * Copyright (C) 2014 STMicroelectronics
+ * Author: Ludovic Barre <Ludovic.barre@st.com>
+ *	   Peter Griffin <peter.griffin@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
+#include <linux/firmware.h>
+#include <linux/elf.h>
+#include <linux/atomic.h>
+#include <linux/remoteproc.h>
+#include <linux/io.h>
+
+#include "st_fdma.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+static inline struct st_fdma_chan *to_st_fdma_chan(struct dma_chan *c)
+{
+	return container_of(c, struct st_fdma_chan, vchan.chan);
+}
+
+static struct st_fdma_desc *to_st_fdma_desc(struct virt_dma_desc *vd)
+{
+	return container_of(vd, struct st_fdma_desc, vdesc);
+}
+
+static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
+{
+	struct st_fdma_dev *fdev = fchan->fdev;
+	u32 req_line_cfg = fchan->cfg.req_line;
+	u32 dreq_line;
+	int try = 0;
+
+	/*
+	 * dreq_mask is shared for n channels of fdma, so all accesses must be
+	 * atomic. if the dreq_mask it change between ffz ant set_bit,
+	 * we retry
+	 */
+	do {
+		if (fdev->dreq_mask == ~0L) {
+			dev_err(fdev->dev, "No req lines available\n");
+			return -EINVAL;
+		}
+
+		if (try || req_line_cfg >= ST_FDMA_NR_DREQS) {
+			dev_err(fdev->dev, "Invalid or used req line\n");
+			return -EINVAL;
+		} else {
+			dreq_line = req_line_cfg;
+		}
+
+		try++;
+	} while (test_and_set_bit(dreq_line, &fdev->dreq_mask));
+
+	dev_dbg(fdev->dev, "get dreq_line:%d mask:%#lx\n",
+		dreq_line, fdev->dreq_mask);
+
+	return dreq_line;
+}
+
+static void st_fdma_dreq_put(struct st_fdma_chan *fchan)
+{
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line);
+	clear_bit(fchan->dreq_line, &fdev->dreq_mask);
+}
+
+static void st_fdma_xfer_desc(struct st_fdma_chan *fchan)
+{
+	struct virt_dma_desc *vdesc;
+	unsigned long nbytes, ch_cmd, cmd;
+
+	vdesc = vchan_next_desc(&fchan->vchan);
+	if (!vdesc)
+		return;
+
+	fchan->fdesc = to_st_fdma_desc(vdesc);
+	nbytes = fchan->fdesc->node[0].desc->nbytes;
+	cmd = FDMA_CMD_START(fchan->vchan.chan.chan_id);
+	ch_cmd = fchan->fdesc->node[0].pdesc | FDMA_CH_CMD_STA_START;
+
+	/* start the channel for the descriptor */
+	fnode_write(fchan, nbytes, FDMA_CNTN_OFST);
+	fchan_write(fchan, ch_cmd, FDMA_CH_CMD_OFST);
+	writel(cmd,
+		fchan->fdev->xp70_rproc->peri + FDMA_CMD_SET_OFST);
+
+	dev_dbg(fchan->fdev->dev, "start chan:%d\n", fchan->vchan.chan.chan_id);
+}
+
+static void st_fdma_ch_sta_update(struct st_fdma_chan *fchan,
+				  unsigned long int_sta)
+{
+	unsigned long ch_sta, ch_err;
+	int ch_id = fchan->vchan.chan.chan_id;
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	ch_sta = fchan_read(fchan, FDMA_CH_CMD_OFST);
+	ch_err = ch_sta & FDMA_CH_CMD_ERR_MASK;
+	ch_sta &= FDMA_CH_CMD_STA_MASK;
+
+	if (int_sta & FDMA_INT_STA_ERR) {
+		dev_warn(fdev->dev, "chan:%d, error:%ld\n", ch_id, ch_err);
+		fchan->status = DMA_ERROR;
+		return;
+	}
+
+	switch (ch_sta) {
+	case FDMA_CH_CMD_STA_PAUSED:
+		fchan->status = DMA_PAUSED;
+		break;
+	case FDMA_CH_CMD_STA_RUNNING:
+		fchan->status = DMA_IN_PROGRESS;
+		break;
+	}
+}
+
+static irqreturn_t st_fdma_irq_handler(int irq, void *dev_id)
+{
+	struct st_fdma_dev *fdev = dev_id;
+	irqreturn_t ret = IRQ_NONE;
+	struct st_fdma_chan *fchan = &fdev->chans[0];
+	unsigned long int_sta, clr;
+
+	int_sta = fdma_read(fdev, FDMA_INT_STA_OFST);
+	clr = int_sta;
+
+	for (; int_sta != 0 ; int_sta >>= 2, fchan++) {
+		if (!(int_sta & (FDMA_INT_STA_CH | FDMA_INT_STA_ERR)))
+			continue;
+
+		spin_lock(&fchan->vchan.lock);
+		st_fdma_ch_sta_update(fchan, int_sta);
+
+		if (fchan->fdesc) {
+			if (!fchan->fdesc->iscyclic) {
+				list_del(&fchan->fdesc->vdesc.node);
+				vchan_cookie_complete(&fchan->fdesc->vdesc);
+				fchan->fdesc = NULL;
+				fchan->status = DMA_COMPLETE;
+			} else {
+				vchan_cyclic_callback(&fchan->fdesc->vdesc);
+			}
+
+			/* Start the next descriptor (if available) */
+			if (!fchan->fdesc)
+				st_fdma_xfer_desc(fchan);
+		}
+
+		spin_unlock(&fchan->vchan.lock);
+		ret = IRQ_HANDLED;
+	}
+
+	fdma_write(fdev, clr, FDMA_INT_CLR_OFST);
+
+	return ret;
+}
+
+static struct dma_chan *st_fdma_of_xlate(struct of_phandle_args *dma_spec,
+					 struct of_dma *ofdma)
+{
+	struct st_fdma_dev *fdev = ofdma->of_dma_data;
+	struct dma_chan *chan;
+	struct st_fdma_chan *fchan;
+
+	if (dma_spec->args_count < 1)
+		return NULL;
+
+	chan = dma_get_any_slave_channel(&fdev->dma_device);
+	if (!chan)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	if (fchan->fdev->dma_device.dev->of_node != dma_spec->np)
+		return NULL;
+
+	fchan->cfg.of_node = dma_spec->np;
+	fchan->cfg.req_line = dma_spec->args[0];
+	fchan->cfg.req_ctrl = 0;
+	fchan->cfg.type = ST_FDMA_TYPE_FREE_RUN;
+
+	if (dma_spec->args_count > 1)
+		fchan->cfg.req_ctrl = dma_spec->args[1] & REQ_CTRL_CFG_MASK;
+
+	if (dma_spec->args_count > 2)
+		fchan->cfg.type = dma_spec->args[2];
+
+	if (fchan->cfg.type == ST_FDMA_TYPE_FREE_RUN) {
+		fchan->dreq_line = 0;
+	} else {
+		fchan->dreq_line = st_fdma_dreq_get(fchan);
+		if (IS_ERR_VALUE(fchan->dreq_line))
+			return NULL;
+	}
+
+	dev_dbg(fdev->dev, "xlate req_line:%d type:%d req_ctrl:%#lx\n",
+		fchan->cfg.req_line, fchan->cfg.type, fchan->cfg.req_ctrl);
+
+	return chan;
+}
+
+static void st_fdma_free_desc(struct virt_dma_desc *vdesc)
+{
+	struct st_fdma_desc *fdesc;
+	int i;
+
+	fdesc = to_st_fdma_desc(vdesc);
+	for (i = 0; i < fdesc->n_nodes; i++)
+		dma_pool_free(fdesc->fchan->node_pool, fdesc->node[i].desc,
+			      fdesc->node[i].pdesc);
+	kfree(fdesc);
+}
+
+static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan,
+					       int sg_len)
+{
+	struct st_fdma_desc *fdesc;
+	int i;
+
+	fdesc = kzalloc(sizeof(*fdesc) +
+			sizeof(struct st_fdma_sw_node) * sg_len, GFP_NOWAIT);
+	if (!fdesc)
+		return NULL;
+
+	fdesc->fchan = fchan;
+	fdesc->n_nodes = sg_len;
+	for (i = 0; i < sg_len; i++) {
+		fdesc->node[i].desc = dma_pool_alloc(fchan->node_pool,
+				GFP_NOWAIT, &fdesc->node[i].pdesc);
+		if (!fdesc->node[i].desc)
+			goto err;
+	}
+	return fdesc;
+
+err:
+	while (--i >= 0)
+		dma_pool_free(fchan->node_pool, fdesc->node[i].desc,
+			      fdesc->node[i].pdesc);
+	kfree(fdesc);
+	return NULL;
+}
+
+static int st_fdma_alloc_chan_res(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ret;
+
+	/* Create the dma pool for descriptor allocation */
+	fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device),
+					    fchan->fdev->dev,
+					    sizeof(struct st_fdma_hw_node),
+					    __alignof__(struct st_fdma_hw_node),
+					    0);
+
+	if (!fchan->node_pool) {
+		dev_err(fchan->fdev->dev, "unable to allocate desc pool\n");
+		return -ENOMEM;
+	}
+
+
+	ret = rproc_boot(fchan->fdev->rproc);
+	if (ret) {
+		dev_err(fchan->fdev->dev, "rproc_boot failed\n");
+		return ret;
+	}
+
+	dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n",
+		fchan->vchan.chan.chan_id, fchan->cfg.type);
+
+	return 0;
+}
+
+static void st_fdma_free_chan_res(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	unsigned long flags;
+
+	LIST_HEAD(head);
+
+	dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
+		__func__, fchan->vchan.chan.chan_id);
+
+	if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
+		st_fdma_dreq_put(fchan);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	fchan->fdesc = NULL;
+	vchan_get_all_descriptors(&fchan->vchan, &head);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	dma_pool_destroy(fchan->node_pool);
+	fchan->node_pool = NULL;
+	memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
+
+	rproc_shutdown(fchan->fdev->rproc);
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_dma_memcpy(
+	struct dma_chan *chan,	dma_addr_t dst, dma_addr_t src,
+	size_t len, unsigned long flags)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	struct st_fdma_hw_node *hw_node;
+
+	if (!len)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	/* We only require a single descriptor */
+	fdesc = st_fdma_alloc_desc(fchan, 1);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	hw_node = fdesc->node[0].desc;
+	hw_node->next = 0;
+	hw_node->control = NODE_CTRL_REQ_MAP_FREE_RUN;
+	hw_node->control |= NODE_CTRL_SRC_INCR;
+	hw_node->control |= NODE_CTRL_DST_INCR;
+	hw_node->control |= NODE_CTRL_INT_EON;
+	hw_node->nbytes = len;
+	hw_node->saddr = src;
+	hw_node->daddr = dst;
+	hw_node->generic.length = len;
+	hw_node->generic.sstride = 0;
+	hw_node->generic.dstride = 0;
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static int config_reqctrl(struct st_fdma_chan *fchan,
+			  enum dma_transfer_direction direction)
+{
+	u32 maxburst = 0, addr = 0;
+	enum dma_slave_buswidth width;
+	int ch_id = fchan->vchan.chan.chan_id;
+	struct st_fdma_dev *fdev = fchan->fdev;
+
+	switch (direction) {
+
+	case DMA_DEV_TO_MEM:
+		fchan->cfg.req_ctrl &= ~REQ_CTRL_WNR;
+		maxburst = fchan->scfg.src_maxburst;
+		width = fchan->scfg.src_addr_width;
+		addr = fchan->scfg.src_addr;
+		break;
+
+	case DMA_MEM_TO_DEV:
+		fchan->cfg.req_ctrl |= REQ_CTRL_WNR;
+		maxburst = fchan->scfg.dst_maxburst;
+		width = fchan->scfg.dst_addr_width;
+		addr = fchan->scfg.dst_addr;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	fchan->cfg.req_ctrl &= ~REQ_CTRL_OPCODE_MASK;
+
+	switch (width) {
+
+	case DMA_SLAVE_BUSWIDTH_1_BYTE:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST1;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_2_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST2;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_4_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST4;
+		break;
+
+	case DMA_SLAVE_BUSWIDTH_8_BYTES:
+		fchan->cfg.req_ctrl |= REQ_CTRL_OPCODE_LD_ST8;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	fchan->cfg.req_ctrl &= ~REQ_CTRL_NUM_OPS_MASK;
+	fchan->cfg.req_ctrl |= REQ_CTRL_NUM_OPS(maxburst-1);
+	dreq_write(fchan, fchan->cfg.req_ctrl, FDMA_REQ_CTRL_OFST);
+
+	fchan->cfg.dev_addr = addr;
+	fchan->cfg.dir = direction;
+
+	dev_dbg(fdev->dev, "chan:%d config_reqctrl:%#x req_ctrl:%#lx\n",
+		ch_id, addr, fchan->cfg.req_ctrl);
+
+	return 0;
+}
+
+static void fill_hw_node(struct st_fdma_hw_node *hw_node,
+			struct st_fdma_chan *fchan,
+			enum dma_transfer_direction direction)
+{
+	if (direction == DMA_MEM_TO_DEV) {
+		hw_node->control |= NODE_CTRL_SRC_INCR;
+		hw_node->control |= NODE_CTRL_DST_STATIC;
+		hw_node->daddr = fchan->cfg.dev_addr;
+	} else {
+		hw_node->control |= NODE_CTRL_SRC_STATIC;
+		hw_node->control |= NODE_CTRL_DST_INCR;
+		hw_node->saddr = fchan->cfg.dev_addr;
+	}
+
+	hw_node->generic.sstride = 0;
+	hw_node->generic.dstride = 0;
+}
+
+static struct st_fdma_chan *st_fdma_prep_common(struct dma_chan *chan,
+		size_t len, enum dma_transfer_direction direction)
+{
+	struct st_fdma_chan *fchan;
+
+	if (!chan || !len)
+		return NULL;
+
+	fchan = to_st_fdma_chan(chan);
+
+	if (!is_slave_direction(direction)) {
+		dev_err(fchan->fdev->dev, "bad direction?\n");
+		return NULL;
+	}
+
+	return fchan;
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_dma_cyclic(
+		struct dma_chan *chan, dma_addr_t buf_addr, size_t len,
+		size_t period_len, enum dma_transfer_direction direction,
+		unsigned long flags)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	int sg_len, i;
+
+	fchan = st_fdma_prep_common(chan, len, direction);
+	if (!fchan)
+		return NULL;
+
+	if (!period_len)
+		return NULL;
+
+	if (config_reqctrl(fchan, direction)) {
+		dev_err(fchan->fdev->dev, "bad width or direction\n");
+		return NULL;
+	}
+
+	/* the buffer length must be a multiple of period_len */
+	if (len % period_len != 0) {
+		dev_err(fchan->fdev->dev, "len is not multiple of period\n");
+		return NULL;
+	}
+
+	sg_len = len / period_len;
+	fdesc = st_fdma_alloc_desc(fchan, sg_len);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	fdesc->iscyclic = true;
+
+	for (i = 0; i < sg_len; i++) {
+		struct st_fdma_hw_node *hw_node = fdesc->node[i].desc;
+
+		hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
+
+		hw_node->control = NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
+		hw_node->control |= NODE_CTRL_INT_EON;
+
+		fill_hw_node(hw_node, fchan, direction);
+
+		if (direction == DMA_MEM_TO_DEV)
+			hw_node->saddr = buf_addr + (i * period_len);
+		else
+			hw_node->daddr = buf_addr + (i * period_len);
+
+		hw_node->nbytes = period_len;
+		hw_node->generic.length = period_len;
+	}
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static struct dma_async_tx_descriptor *st_fdma_prep_slave_sg(
+		struct dma_chan *chan, struct scatterlist *sgl,
+		unsigned int sg_len, enum dma_transfer_direction direction,
+		unsigned long flags, void *context)
+{
+	struct st_fdma_chan *fchan;
+	struct st_fdma_desc *fdesc;
+	struct st_fdma_hw_node *hw_node;
+	struct scatterlist *sg;
+	int i;
+
+	fchan = st_fdma_prep_common(chan, sg_len, direction);
+	if (!fchan)
+		return NULL;
+
+	if (!sgl)
+		return NULL;
+
+	fdesc = st_fdma_alloc_desc(fchan, sg_len);
+	if (!fdesc) {
+		dev_err(fchan->fdev->dev, "no memory for desc\n");
+		return NULL;
+	}
+
+	fdesc->iscyclic = false;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		hw_node = fdesc->node[i].desc;
+
+		hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
+		hw_node->control = NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
+
+		fill_hw_node(hw_node, fchan, direction);
+
+		if (direction == DMA_MEM_TO_DEV)
+			hw_node->saddr = sg_dma_address(sg);
+		else
+			hw_node->daddr = sg_dma_address(sg);
+
+		hw_node->nbytes = sg_dma_len(sg);
+		hw_node->generic.length = sg_dma_len(sg);
+	}
+
+	/* interrupt at end of last node */
+	hw_node->control |= NODE_CTRL_INT_EON;
+
+	return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
+}
+
+static size_t st_fdma_desc_residue(struct st_fdma_chan *fchan,
+				   struct virt_dma_desc *vdesc,
+				   bool in_progress)
+{
+	struct st_fdma_desc *fdesc = fchan->fdesc;
+	size_t residue = 0;
+	dma_addr_t cur_addr = 0;
+	int i;
+
+	if (in_progress) {
+		cur_addr = fchan_read(fchan, FDMA_CH_CMD_OFST);
+		cur_addr &= FDMA_CH_CMD_DATA_MASK;
+	}
+
+	for (i = fchan->fdesc->n_nodes - 1 ; i >= 0; i--) {
+		if (cur_addr == fdesc->node[i].pdesc) {
+			residue += fnode_read(fchan, FDMA_CNTN_OFST);
+			break;
+		}
+		residue += fdesc->node[i].desc->nbytes;
+	}
+
+	return residue;
+}
+
+static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
+					 dma_cookie_t cookie,
+					 struct dma_tx_state *txstate)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	struct virt_dma_desc *vd;
+	enum dma_status ret;
+	unsigned long flags;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_COMPLETE)
+		return ret;
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	vd = vchan_find_desc(&fchan->vchan, cookie);
+	if (fchan->fdesc && cookie == fchan->fdesc->vdesc.tx.cookie)
+		txstate->residue = st_fdma_desc_residue(fchan, vd, true);
+	else if (vd)
+		txstate->residue = st_fdma_desc_residue(fchan, vd, false);
+	else
+		txstate->residue = 0;
+
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return ret;
+}
+
+static void st_fdma_issue_pending(struct dma_chan *chan)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+
+	if (vchan_issue_pending(&fchan->vchan) && !fchan->fdesc)
+		st_fdma_xfer_desc(fchan);
+
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+}
+
+static int st_fdma_pause(struct dma_chan *chan)
+{
+	unsigned long flags;
+	LIST_HEAD(head);
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+	unsigned long cmd = FDMA_CMD_PAUSE(ch_id);
+
+	dev_dbg(fchan->fdev->dev, "pause chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	if (fchan->fdesc)
+		fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return 0;
+}
+
+static int st_fdma_resume(struct dma_chan *chan)
+{
+	unsigned long flags;
+	unsigned long val;
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+
+	dev_dbg(fchan->fdev->dev, "resume chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	if (fchan->fdesc) {
+		val = fchan_read(fchan, FDMA_CH_CMD_OFST);
+		val &= FDMA_CH_CMD_DATA_MASK;
+		fchan_write(fchan, val, FDMA_CH_CMD_OFST);
+	}
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+
+	return 0;
+}
+
+static int st_fdma_terminate_all(struct dma_chan *chan)
+{
+	unsigned long flags;
+	LIST_HEAD(head);
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+	int ch_id = fchan->vchan.chan.chan_id;
+	unsigned long cmd = FDMA_CMD_PAUSE(ch_id);
+
+	dev_dbg(fchan->fdev->dev, "terminate chan:%d\n", ch_id);
+
+	spin_lock_irqsave(&fchan->vchan.lock, flags);
+	fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST);
+	fchan->fdesc = NULL;
+	vchan_get_all_descriptors(&fchan->vchan, &head);
+	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
+	vchan_dma_desc_free_list(&fchan->vchan, &head);
+
+	return 0;
+}
+
+static int st_fdma_slave_config(struct dma_chan *chan,
+				struct dma_slave_config *slave_cfg)
+{
+	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
+
+	memcpy(&fchan->scfg, slave_cfg, sizeof(fchan->scfg));
+	return 0;
+}
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_11 = {
+	.name = "STiH407",
+	.id = 0,
+};
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_12 = {
+	.name = "STiH407",
+	.id = 1,
+};
+
+static const struct st_fdma_driverdata fdma_mpe31_stih407_13 = {
+	.name = "STiH407",
+	.id = 2,
+};
+
+static const struct of_device_id st_fdma_match[] = {
+	{ .compatible = "st,stih407-fdma-mpe31-11"
+	  , .data = &fdma_mpe31_stih407_11 },
+	{ .compatible = "st,stih407-fdma-mpe31-12"
+	  , .data = &fdma_mpe31_stih407_12 },
+	{ .compatible = "st,stih407-fdma-mpe31-13"
+	  , .data = &fdma_mpe31_stih407_13 },
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_fdma_match);
+
+static int st_fdma_parse_dt(struct platform_device *pdev,
+			const struct st_fdma_driverdata *drvdata,
+			struct st_fdma_dev *fdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	if (!np)
+		goto err;
+
+	ret = of_property_read_u32(np, "dma-channels", &fdev->nr_channels);
+	if (ret)
+		goto err;
+
+	snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf",
+		drvdata->name, drvdata->id);
+
+err:
+	return ret;
+}
+#define FDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+static int st_fdma_probe(struct platform_device *pdev)
+{
+	struct st_fdma_dev *fdev;
+	const struct of_device_id *match;
+	struct device_node *np = pdev->dev.of_node;
+	const struct st_fdma_driverdata *drvdata;
+	int ret, i;
+
+	match = of_match_device((st_fdma_match), &pdev->dev);
+	if (!match || !match->data) {
+		dev_err(&pdev->dev, "No device match found\n");
+		return -ENODEV;
+	}
+
+	drvdata = match->data;
+
+	fdev = devm_kzalloc(&pdev->dev, sizeof(*fdev), GFP_KERNEL);
+	if (!fdev)
+		return -ENOMEM;
+
+	ret = st_fdma_parse_dt(pdev, drvdata, fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to find platform data\n");
+		goto err;
+	}
+
+	fdev->chans = devm_kzalloc(&pdev->dev,
+				   fdev->nr_channels
+				   * sizeof(struct st_fdma_chan), GFP_KERNEL);
+	if (!fdev->chans)
+		return -ENOMEM;
+
+	fdev->dev = &pdev->dev;
+	fdev->drvdata = drvdata;
+	platform_set_drvdata(pdev, fdev);
+
+	fdev->irq = platform_get_irq(pdev, 0);
+	if (fdev->irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource\n");
+		return -EINVAL;
+	}
+
+	ret = devm_request_irq(&pdev->dev, fdev->irq, st_fdma_irq_handler, 0,
+			       dev_name(&pdev->dev), fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request irq\n");
+		goto err;
+	}
+
+	fdev->rproc = xp70_rproc_alloc(pdev, fdev->fw_name);
+	if (!fdev->rproc) {
+		dev_err(&pdev->dev, "xp70_rproc_init failed\n");
+		ret = PTR_ERR(fdev->rproc);
+		goto err;
+	}
+
+	fdev->xp70_rproc = fdev->rproc->priv;
+
+	/* Initialise list of FDMA channels */
+	INIT_LIST_HEAD(&fdev->dma_device.channels);
+	for (i = 0; i < fdev->nr_channels; i++) {
+		struct st_fdma_chan *fchan = &fdev->chans[i];
+
+		fchan->fdev = fdev;
+		fchan->vchan.desc_free = st_fdma_free_desc;
+		vchan_init(&fchan->vchan, &fdev->dma_device);
+	}
+
+	/* Initialise the FDMA dreq (reserve 0 & 31 for FDMA use) */
+	fdev->dreq_mask = BIT(0) | BIT(31);
+
+	dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);
+	dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
+	dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);
+
+	fdev->dma_device.dev = &pdev->dev;
+	fdev->dma_device.device_alloc_chan_resources = st_fdma_alloc_chan_res;
+	fdev->dma_device.device_free_chan_resources = st_fdma_free_chan_res;
+	fdev->dma_device.device_prep_dma_cyclic	= st_fdma_prep_dma_cyclic;
+	fdev->dma_device.device_prep_slave_sg = st_fdma_prep_slave_sg;
+	fdev->dma_device.device_prep_dma_memcpy = st_fdma_prep_dma_memcpy;
+	fdev->dma_device.device_tx_status = st_fdma_tx_status;
+	fdev->dma_device.device_issue_pending = st_fdma_issue_pending;
+	fdev->dma_device.device_terminate_all = st_fdma_terminate_all;
+	fdev->dma_device.device_config = st_fdma_slave_config;
+	fdev->dma_device.device_pause = st_fdma_pause;
+	fdev->dma_device.device_resume = st_fdma_resume;
+
+	fdev->dma_device.src_addr_widths = FDMA_DMA_BUSWIDTHS;
+	fdev->dma_device.dst_addr_widths = FDMA_DMA_BUSWIDTHS;
+	fdev->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	fdev->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+
+	ret = dma_async_device_register(&fdev->dma_device);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register DMA device\n");
+		goto err_rproc;
+	}
+
+	ret = of_dma_controller_register(np, st_fdma_of_xlate, fdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register controller\n");
+		goto err_dma_dev;
+	}
+
+	dev_info(&pdev->dev, "ST FDMA engine driver, irq:%d\n", fdev->irq);
+
+	return 0;
+
+err_dma_dev:
+	dma_async_device_unregister(&fdev->dma_device);
+err_rproc:
+	xp70_rproc_put(fdev->xp70_rproc);
+err:
+	return ret;
+}
+
+static int st_fdma_remove(struct platform_device *pdev)
+{
+	struct st_fdma_dev *fdev = platform_get_drvdata(pdev);
+
+	devm_free_irq(&pdev->dev, fdev->irq, fdev);
+	xp70_rproc_put(fdev->xp70_rproc);
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&fdev->dma_device);
+
+	return 0;
+}
+
+static struct platform_driver st_fdma_platform_driver = {
+	.driver = {
+		.name = "st-fdma",
+		.of_match_table = st_fdma_match,
+	},
+	.probe = st_fdma_probe,
+	.remove = st_fdma_remove,
+};
+module_platform_driver(st_fdma_platform_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
+MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>");
+MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
-- 
1.9.1

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

* [PATCH v4 07/18] ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

These nodes are required to get the fdma driver working
on STiH407 based silicon.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 52 +++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 81f8121..b423836 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -694,5 +694,57 @@
 			clocks          = <&clk_sysin>;
 			status		= "okay";
 		};
+
+		/* fdma audio */
+		fdma0: dma-controller@8e20000 {
+			compatible = "st,stih407-fdma-mpe31-11", "st,xp70-rproc";
+			reg = <0x8e20000 0x8000>,
+			      <0x8e30000 0x3000>,
+			      <0x8e37000 0x1000>,
+			      <0x8e38000 0x8000>;
+			reg-names = "slimcore", "dmem", "peripherals", "imem";
+			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+				 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+				 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+				 <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_NONE>;
+			dma-channels = <16>;
+			#dma-cells = <3>;
+		};
+
+		/* fdma app */
+		fdma1: dma-controller@8e40000 {
+			compatible = "st,stih407-fdma-mpe31-12", "st,xp70-rproc";
+			reg = <0x8e40000 0x8000>,
+			      <0x8e50000 0x3000>,
+			      <0x8e57000 0x1000>,
+			      <0x8e58000 0x8000>;
+			reg-names = "slimcore", "dmem", "peripherals", "imem";
+			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+				<&clk_s_c0_flexgen CLK_TX_ICN_DMU>,
+				<&clk_s_c0_flexgen CLK_TX_ICN_DMU>,
+				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
+
+			interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>;
+			dma-channels = <16>;
+			#dma-cells = <3>;
+		};
+
+		/* fdma free running */
+		fdma2: dma-controller@8e60000 {
+			compatible = "st,stih407-fdma-mpe31-13", "st,xp70-rproc";
+			reg = <0x8e60000 0x8000>,
+			      <0x8e70000 0x3000>,
+			      <0x8e77000 0x1000>,
+			      <0x8e78000 0x8000>;
+			reg-names = "slimcore", "dmem", "peripherals", "imem";
+			interrupts = <GIC_SPI 9 IRQ_TYPE_NONE>;
+			dma-channels = <16>;
+			#dma-cells = <3>;
+			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+				<&clk_s_c0_flexgen CLK_EXT2F_A9>,
+				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
+				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 07/18] ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

These nodes are required to get the fdma driver working
on STiH407 based silicon.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 52 +++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 81f8121..b423836 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -694,5 +694,57 @@
 			clocks          = <&clk_sysin>;
 			status		= "okay";
 		};
+
+		/* fdma audio */
+		fdma0: dma-controller at 8e20000 {
+			compatible = "st,stih407-fdma-mpe31-11", "st,xp70-rproc";
+			reg = <0x8e20000 0x8000>,
+			      <0x8e30000 0x3000>,
+			      <0x8e37000 0x1000>,
+			      <0x8e38000 0x8000>;
+			reg-names = "slimcore", "dmem", "peripherals", "imem";
+			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+				 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+				 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+				 <&clk_s_c0_flexgen CLK_EXT2F_A9>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_NONE>;
+			dma-channels = <16>;
+			#dma-cells = <3>;
+		};
+
+		/* fdma app */
+		fdma1: dma-controller at 8e40000 {
+			compatible = "st,stih407-fdma-mpe31-12", "st,xp70-rproc";
+			reg = <0x8e40000 0x8000>,
+			      <0x8e50000 0x3000>,
+			      <0x8e57000 0x1000>,
+			      <0x8e58000 0x8000>;
+			reg-names = "slimcore", "dmem", "peripherals", "imem";
+			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+				<&clk_s_c0_flexgen CLK_TX_ICN_DMU>,
+				<&clk_s_c0_flexgen CLK_TX_ICN_DMU>,
+				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
+
+			interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>;
+			dma-channels = <16>;
+			#dma-cells = <3>;
+		};
+
+		/* fdma free running */
+		fdma2: dma-controller at 8e60000 {
+			compatible = "st,stih407-fdma-mpe31-13", "st,xp70-rproc";
+			reg = <0x8e60000 0x8000>,
+			      <0x8e70000 0x3000>,
+			      <0x8e77000 0x1000>,
+			      <0x8e78000 0x8000>;
+			reg-names = "slimcore", "dmem", "peripherals", "imem";
+			interrupts = <GIC_SPI 9 IRQ_TYPE_NONE>;
+			dma-channels = <16>;
+			#dma-cells = <3>;
+			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
+				<&clk_s_c0_flexgen CLK_EXT2F_A9>,
+				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
+				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 08/18] MAINTAINERS: Add FDMA driver files to STi section.
  2016-05-25 16:06 ` Peter Griffin
  (?)
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch adds the FDMA driver files to the STi
section of the maintainers file.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index de99aec..627a2e0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1638,6 +1638,7 @@ F:	arch/arm/boot/dts/sti*
 F:	drivers/char/hw_random/st-rng.c
 F:	drivers/clocksource/arm_global_timer.c
 F:	drivers/clocksource/clksrc_st_lpc.c
+F:	drivers/dma/st_fdma*
 F:	drivers/i2c/busses/i2c-st.c
 F:	drivers/media/rc/st_rc.c
 F:	drivers/media/platform/sti/c8sectpfe/
-- 
1.9.1

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

* [PATCH v4 08/18] MAINTAINERS: Add FDMA driver files to STi section.
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, devicetree, linux-remoteproc, lee.jones, dmaengine

This patch adds the FDMA driver files to the STi
section of the maintainers file.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index de99aec..627a2e0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1638,6 +1638,7 @@ F:	arch/arm/boot/dts/sti*
 F:	drivers/char/hw_random/st-rng.c
 F:	drivers/clocksource/arm_global_timer.c
 F:	drivers/clocksource/clksrc_st_lpc.c
+F:	drivers/dma/st_fdma*
 F:	drivers/i2c/busses/i2c-st.c
 F:	drivers/media/rc/st_rc.c
 F:	drivers/media/platform/sti/c8sectpfe/
-- 
1.9.1

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

* [PATCH v4 08/18] MAINTAINERS: Add FDMA driver files to STi section.
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the FDMA driver files to the STi
section of the maintainers file.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index de99aec..627a2e0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1638,6 +1638,7 @@ F:	arch/arm/boot/dts/sti*
 F:	drivers/char/hw_random/st-rng.c
 F:	drivers/clocksource/arm_global_timer.c
 F:	drivers/clocksource/clksrc_st_lpc.c
+F:	drivers/dma/st_fdma*
 F:	drivers/i2c/busses/i2c-st.c
 F:	drivers/media/rc/st_rc.c
 F:	drivers/media/platform/sti/c8sectpfe/
-- 
1.9.1

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

* [PATCH v4 09/18] ARM: multi_v7_defconfig: Enable STi FDMA driver
  2016-05-25 16:06 ` Peter Griffin
  (?)
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This DMA controller is found on all STi chipsets.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index d319d8f..5eee45b 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -728,6 +728,7 @@ CONFIG_DMA_OMAP=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_XILINX_VDMA=y
 CONFIG_DMA_SUN6I=y
+CONFIG_ST_FDMA=m
 CONFIG_STAGING=y
 CONFIG_SENSORS_ISL29018=y
 CONFIG_SENSORS_ISL29028=y
-- 
1.9.1

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

* [PATCH v4 09/18] ARM: multi_v7_defconfig: Enable STi FDMA driver
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, devicetree, linux-remoteproc, lee.jones, dmaengine

This DMA controller is found on all STi chipsets.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index d319d8f..5eee45b 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -728,6 +728,7 @@ CONFIG_DMA_OMAP=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_XILINX_VDMA=y
 CONFIG_DMA_SUN6I=y
+CONFIG_ST_FDMA=m
 CONFIG_STAGING=y
 CONFIG_SENSORS_ISL29018=y
 CONFIG_SENSORS_ISL29028=y
-- 
1.9.1

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

* [PATCH v4 09/18] ARM: multi_v7_defconfig: Enable STi FDMA driver
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This DMA controller is found on all STi chipsets.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index d319d8f..5eee45b 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -728,6 +728,7 @@ CONFIG_DMA_OMAP=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_XILINX_VDMA=y
 CONFIG_DMA_SUN6I=y
+CONFIG_ST_FDMA=m
 CONFIG_STAGING=y
 CONFIG_SENSORS_ISL29018=y
 CONFIG_SENSORS_ISL29028=y
-- 
1.9.1

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

* [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
  2016-05-25 16:06 ` Peter Griffin
  (?)
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine,
	linux-remoteproc, arnaud.pouliquen, broonie

uniperiph-id, version and mode are ST specific bindings and
need the 'st,' prefix. Update the examples, as otherwise copying
them yields a runtime error parsing the DT node.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Cc: arnaud.pouliquen@st.com
Cc: broonie@kernel.org
---
 .../devicetree/bindings/sound/st,sti-asoc-card.txt   | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
index 028fa1c..fe1b72c 100644
--- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
@@ -33,7 +33,7 @@ Required properties:
 	"tx" for "st,sti-uni-player" compatibility
 	"rx" for "st,sti-uni-reader" compatibility
 
-  - version: IP version integrated in SOC.
+  - st,version: IP version integrated in SOC.
 
   - dai-name: DAI name that describes the IP.
 
@@ -41,9 +41,9 @@ Required properties ("st,sti-uni-player" compatibility only):
   - clocks: CPU_DAI IP clock source, listed in the same order than the
 	    CPU_DAI properties.
 
-  - uniperiph-id: internal SOC IP instance ID.
+  - st,uniperiph-id: internal SOC IP instance ID.
 
-  - IP mode: IP working mode depending on associated codec.
+  - st,mode: IP working mode depending on associated codec.
 	"HDMI" connected to HDMI codec IP and IEC HDMI formats.
 	"SPDIF"connected to SPDIF codec and support SPDIF formats.
 	"PCM"  PCM standard mode for I2S or TDM bus.
@@ -67,9 +67,9 @@ Example:
 		dmas = <&fdma0 4 0 1>;
 		dai-name = "Uni Player #1 (DAC)";
 		dma-names = "tx";
-		uniperiph-id = <2>;
-		version = <5>;
-		mode = "PCM";
+		st,uniperiph-id = <2>;
+		st,version = <5>;
+		st,mode = "PCM";
 	};
 
 	sti_uni_player3: sti-uni-player@3 {
@@ -83,9 +83,9 @@ Example:
 		dmas = <&fdma0 7 0 1>;
 		dma-names = "tx";
 		dai-name = "Uni Player #1 (PIO)";
-		uniperiph-id = <3>;
-		version = <5>;
-		mode = "SPDIF";
+		st,uniperiph-id = <3>;
+		st,version = <5>;
+		st,mode = "SPDIF";
 	};
 
 	sti_uni_reader1: sti-uni-reader@1 {
@@ -98,7 +98,7 @@ Example:
 		dmas = <&fdma0 6 0 1>;
 		dma-names = "rx";
 		dai-name = "Uni Reader #1 (HDMI RX)";
-		version = <3>;
+		st,version = <3>;
 	};
 
 2) sti-sas-codec: internal audio codec IPs driver
-- 
1.9.1

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

* [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: devicetree, arnaud.pouliquen, linux-remoteproc, peter.griffin,
	broonie, dmaengine, lee.jones

uniperiph-id, version and mode are ST specific bindings and
need the 'st,' prefix. Update the examples, as otherwise copying
them yields a runtime error parsing the DT node.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Cc: arnaud.pouliquen@st.com
Cc: broonie@kernel.org
---
 .../devicetree/bindings/sound/st,sti-asoc-card.txt   | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
index 028fa1c..fe1b72c 100644
--- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
@@ -33,7 +33,7 @@ Required properties:
 	"tx" for "st,sti-uni-player" compatibility
 	"rx" for "st,sti-uni-reader" compatibility
 
-  - version: IP version integrated in SOC.
+  - st,version: IP version integrated in SOC.
 
   - dai-name: DAI name that describes the IP.
 
@@ -41,9 +41,9 @@ Required properties ("st,sti-uni-player" compatibility only):
   - clocks: CPU_DAI IP clock source, listed in the same order than the
 	    CPU_DAI properties.
 
-  - uniperiph-id: internal SOC IP instance ID.
+  - st,uniperiph-id: internal SOC IP instance ID.
 
-  - IP mode: IP working mode depending on associated codec.
+  - st,mode: IP working mode depending on associated codec.
 	"HDMI" connected to HDMI codec IP and IEC HDMI formats.
 	"SPDIF"connected to SPDIF codec and support SPDIF formats.
 	"PCM"  PCM standard mode for I2S or TDM bus.
@@ -67,9 +67,9 @@ Example:
 		dmas = <&fdma0 4 0 1>;
 		dai-name = "Uni Player #1 (DAC)";
 		dma-names = "tx";
-		uniperiph-id = <2>;
-		version = <5>;
-		mode = "PCM";
+		st,uniperiph-id = <2>;
+		st,version = <5>;
+		st,mode = "PCM";
 	};
 
 	sti_uni_player3: sti-uni-player@3 {
@@ -83,9 +83,9 @@ Example:
 		dmas = <&fdma0 7 0 1>;
 		dma-names = "tx";
 		dai-name = "Uni Player #1 (PIO)";
-		uniperiph-id = <3>;
-		version = <5>;
-		mode = "SPDIF";
+		st,uniperiph-id = <3>;
+		st,version = <5>;
+		st,mode = "SPDIF";
 	};
 
 	sti_uni_reader1: sti-uni-reader@1 {
@@ -98,7 +98,7 @@ Example:
 		dmas = <&fdma0 6 0 1>;
 		dma-names = "rx";
 		dai-name = "Uni Reader #1 (HDMI RX)";
-		version = <3>;
+		st,version = <3>;
 	};
 
 2) sti-sas-codec: internal audio codec IPs driver
-- 
1.9.1

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

* [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

uniperiph-id, version and mode are ST specific bindings and
need the 'st,' prefix. Update the examples, as otherwise copying
them yields a runtime error parsing the DT node.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Cc: arnaud.pouliquen at st.com
Cc: broonie at kernel.org
---
 .../devicetree/bindings/sound/st,sti-asoc-card.txt   | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
index 028fa1c..fe1b72c 100644
--- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
@@ -33,7 +33,7 @@ Required properties:
 	"tx" for "st,sti-uni-player" compatibility
 	"rx" for "st,sti-uni-reader" compatibility
 
-  - version: IP version integrated in SOC.
+  - st,version: IP version integrated in SOC.
 
   - dai-name: DAI name that describes the IP.
 
@@ -41,9 +41,9 @@ Required properties ("st,sti-uni-player" compatibility only):
   - clocks: CPU_DAI IP clock source, listed in the same order than the
 	    CPU_DAI properties.
 
-  - uniperiph-id: internal SOC IP instance ID.
+  - st,uniperiph-id: internal SOC IP instance ID.
 
-  - IP mode: IP working mode depending on associated codec.
+  - st,mode: IP working mode depending on associated codec.
 	"HDMI" connected to HDMI codec IP and IEC HDMI formats.
 	"SPDIF"connected to SPDIF codec and support SPDIF formats.
 	"PCM"  PCM standard mode for I2S or TDM bus.
@@ -67,9 +67,9 @@ Example:
 		dmas = <&fdma0 4 0 1>;
 		dai-name = "Uni Player #1 (DAC)";
 		dma-names = "tx";
-		uniperiph-id = <2>;
-		version = <5>;
-		mode = "PCM";
+		st,uniperiph-id = <2>;
+		st,version = <5>;
+		st,mode = "PCM";
 	};
 
 	sti_uni_player3: sti-uni-player at 3 {
@@ -83,9 +83,9 @@ Example:
 		dmas = <&fdma0 7 0 1>;
 		dma-names = "tx";
 		dai-name = "Uni Player #1 (PIO)";
-		uniperiph-id = <3>;
-		version = <5>;
-		mode = "SPDIF";
+		st,uniperiph-id = <3>;
+		st,version = <5>;
+		st,mode = "SPDIF";
 	};
 
 	sti_uni_reader1: sti-uni-reader at 1 {
@@ -98,7 +98,7 @@ Example:
 		dmas = <&fdma0 6 0 1>;
 		dma-names = "rx";
 		dai-name = "Uni Reader #1 (HDMI RX)";
-		version = <3>;
+		st,version = <3>;
 	};
 
 2) sti-sas-codec: internal audio codec IPs driver
-- 
1.9.1

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

* [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine,
	linux-remoteproc, arnaud.pouliquen, broonie

This patch enables the STi ALSA drivers found on STi platforms
as well as the simple-card driver which is a dependency to have
working sound.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Cc: arnaud.pouliquen@st.com
Cc: broonie@kernel.org
---
 arch/arm/configs/multi_v7_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 5eee45b..0ced665 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -589,6 +589,9 @@ CONFIG_SND_SOC_AK4642=m
 CONFIG_SND_SOC_SGTL5000=m
 CONFIG_SND_SOC_SPDIF=m
 CONFIG_SND_SOC_WM8978=m
+CONFIG_SND_SOC_STI=m
+CONFIG_SND_SOC_STI_SAS=m
+CONFIG_SND_SIMPLE_CARD=m
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_MVEBU=y
-- 
1.9.1

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

* [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch enables the STi ALSA drivers found on STi platforms
as well as the simple-card driver which is a dependency to have
working sound.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Cc: arnaud.pouliquen at st.com
Cc: broonie at kernel.org
---
 arch/arm/configs/multi_v7_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 5eee45b..0ced665 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -589,6 +589,9 @@ CONFIG_SND_SOC_AK4642=m
 CONFIG_SND_SOC_SGTL5000=m
 CONFIG_SND_SOC_SPDIF=m
 CONFIG_SND_SOC_WM8978=m
+CONFIG_SND_SOC_STI=m
+CONFIG_SND_SOC_STI_SAS=m
+CONFIG_SND_SIMPLE_CARD=m
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_MVEBU=y
-- 
1.9.1

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

* [PATCH v4 12/18] ARM: DT: STiH407: Add i2s_out pinctrl configuration
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch adds the pinctrl config for the i2s_out pins
used by the uniperif player IP.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-pinctrl.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index a538ae5..0fb5c8a 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -1067,6 +1067,29 @@
 				};
 			};
 
+			i2s_out {
+				pinctrl_i2s_8ch_out: i2s_8ch_out{
+					st,pins {
+						mclk = <&pio33 5 ALT1 OUT>;
+						lrclk = <&pio33 7 ALT1 OUT>;
+						sclk = <&pio33 6 ALT1 OUT>;
+						data0 = <&pio33 4 ALT1 OUT>;
+						data1 = <&pio34 0 ALT1 OUT>;
+						data2 = <&pio34 1 ALT1 OUT>;
+						data3 = <&pio34 2 ALT1 OUT>;
+					};
+				};
+
+				pinctrl_i2s_2ch_out: i2s_2ch_out{
+					st,pins {
+						mclk = <&pio33 5 ALT1 OUT>;
+						lrclk = <&pio33 7 ALT1 OUT>;
+						sclk = <&pio33 6 ALT1 OUT>;
+						data0 = <&pio33 4 ALT1 OUT>;
+					};
+				};
+			};
+
 			serial3 {
 				pinctrl_serial3: serial3-0 {
 					st,pins {
-- 
1.9.1

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

* [PATCH v4 12/18] ARM: DT: STiH407: Add i2s_out pinctrl configuration
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the pinctrl config for the i2s_out pins
used by the uniperif player IP.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-pinctrl.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index a538ae5..0fb5c8a 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -1067,6 +1067,29 @@
 				};
 			};
 
+			i2s_out {
+				pinctrl_i2s_8ch_out: i2s_8ch_out{
+					st,pins {
+						mclk = <&pio33 5 ALT1 OUT>;
+						lrclk = <&pio33 7 ALT1 OUT>;
+						sclk = <&pio33 6 ALT1 OUT>;
+						data0 = <&pio33 4 ALT1 OUT>;
+						data1 = <&pio34 0 ALT1 OUT>;
+						data2 = <&pio34 1 ALT1 OUT>;
+						data3 = <&pio34 2 ALT1 OUT>;
+					};
+				};
+
+				pinctrl_i2s_2ch_out: i2s_2ch_out{
+					st,pins {
+						mclk = <&pio33 5 ALT1 OUT>;
+						lrclk = <&pio33 7 ALT1 OUT>;
+						sclk = <&pio33 6 ALT1 OUT>;
+						data0 = <&pio33 4 ALT1 OUT>;
+					};
+				};
+			};
+
 			serial3 {
 				pinctrl_serial3: serial3-0 {
 					st,pins {
-- 
1.9.1

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

* [PATCH v4 13/18] ARM: DT: STiH407: Add i2s_in pinctrl configuration
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch adds the pinctrl config for the i2s_in pins
used by the uniperif reader IP.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-pinctrl.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index 0fb5c8a..537db7e 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -1090,6 +1090,30 @@
 				};
 			};
 
+			i2s_in {
+				pinctrl_i2s_8ch_in: i2s_8ch_in{
+					st,pins {
+						mclk = <&pio32 5 ALT1 IN>;
+						lrclk = <&pio32 7 ALT1 IN>;
+						sclk = <&pio32 6 ALT1 IN>;
+						data0 = <&pio32 4 ALT1 IN>;
+						data1 = <&pio33 0 ALT1 IN>;
+						data2 = <&pio33 1 ALT1 IN>;
+						data3 = <&pio33 2 ALT1 IN>;
+						data4 = <&pio33 3 ALT1 IN>;
+					};
+				};
+
+				pinctrl_i2s_2ch_in: i2s_2ch_in{
+					st,pins {
+						mclk = <&pio32 5 ALT1 IN>;
+						lrclk = <&pio32 7 ALT1 IN>;
+						sclk = <&pio32 6 ALT1 IN>;
+						data0 = <&pio32 4 ALT1 IN>;
+					};
+				};
+			};
+
 			serial3 {
 				pinctrl_serial3: serial3-0 {
 					st,pins {
-- 
1.9.1

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

* [PATCH v4 13/18] ARM: DT: STiH407: Add i2s_in pinctrl configuration
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the pinctrl config for the i2s_in pins
used by the uniperif reader IP.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-pinctrl.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index 0fb5c8a..537db7e 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -1090,6 +1090,30 @@
 				};
 			};
 
+			i2s_in {
+				pinctrl_i2s_8ch_in: i2s_8ch_in{
+					st,pins {
+						mclk = <&pio32 5 ALT1 IN>;
+						lrclk = <&pio32 7 ALT1 IN>;
+						sclk = <&pio32 6 ALT1 IN>;
+						data0 = <&pio32 4 ALT1 IN>;
+						data1 = <&pio33 0 ALT1 IN>;
+						data2 = <&pio33 1 ALT1 IN>;
+						data3 = <&pio33 2 ALT1 IN>;
+						data4 = <&pio33 3 ALT1 IN>;
+					};
+				};
+
+				pinctrl_i2s_2ch_in: i2s_2ch_in{
+					st,pins {
+						mclk = <&pio32 5 ALT1 IN>;
+						lrclk = <&pio32 7 ALT1 IN>;
+						sclk = <&pio32 6 ALT1 IN>;
+						data0 = <&pio32 4 ALT1 IN>;
+					};
+				};
+			};
+
 			serial3 {
 				pinctrl_serial3: serial3-0 {
 					st,pins {
-- 
1.9.1

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

* [PATCH v4 14/18] ARM: DT: STiH407: Add spdif_out pinctrl config
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch adds the pinctrl config for the spidf out
pins used by the sasg codec IP.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-pinctrl.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index 537db7e..598dbab 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -1114,6 +1114,14 @@
 				};
 			};
 
+			spdif_out {
+				pinctrl_spdif_out: spdif_out{
+					st,pins {
+						spdif_out = <&pio34 7 ALT1 OUT>;
+					};
+				};
+			};
+
 			serial3 {
 				pinctrl_serial3: serial3-0 {
 					st,pins {
-- 
1.9.1

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

* [PATCH v4 14/18] ARM: DT: STiH407: Add spdif_out pinctrl config
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the pinctrl config for the spidf out
pins used by the sasg codec IP.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-pinctrl.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index 537db7e..598dbab 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -1114,6 +1114,14 @@
 				};
 			};
 
+			spdif_out {
+				pinctrl_spdif_out: spdif_out{
+					st,pins {
+						spdif_out = <&pio34 7 ALT1 OUT>;
+					};
+				};
+			};
+
 			serial3 {
 				pinctrl_serial3: serial3-0 {
 					st,pins {
-- 
1.9.1

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

* [PATCH v4 15/18] ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch adds the dt node for the internal audio
codec IP.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index b423836..60f95b6 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -746,5 +746,14 @@
 				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
 				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
 		};
+
+		sti_sasg_codec: sti-sasg-codec {
+			compatible = "st,stih407-sas-codec";
+			#sound-dai-cells = <1>;
+			status = "okay";
+			st,syscfg = <&syscfg_core>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_spdif_out >;
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 15/18] ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the dt node for the internal audio
codec IP.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index b423836..60f95b6 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -746,5 +746,14 @@
 				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
 				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
 		};
+
+		sti_sasg_codec: sti-sasg-codec {
+			compatible = "st,stih407-sas-codec";
+			#sound-dai-cells = <1>;
+			status = "okay";
+			st,syscfg = <&syscfg_core>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_spdif_out >;
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch adds the DT nodes for the uniperif player
IP blocks found on STiH407 family silicon.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 60f95b6..7ca149b 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -755,5 +755,81 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spdif_out >;
 		};
+
+		sti_uni_player0: sti-uni-player@0 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D80000 0x158>;
+			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 2 0 1>;
+			dai-name = "Uni Player #0 (HDMI)";
+			dma-names = "tx";
+			st,uniperiph-id = <0>;
+			st,version = <5>;
+			st,mode = "HDMI";
+		};
+
+		sti_uni_player1: sti-uni-player@1 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D81000 0x158>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 3 0 1>;
+			dai-name = "Uni Player #1 (PIO)";
+			dma-names = "tx";
+			st,uniperiph-id = <1>;
+			st,version = <5>;
+			st,mode = "PCM";
+		};
+
+		sti_uni_player2: sti-uni-player@2 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D82000 0x158>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 4 0 1>;
+			dai-name = "Uni Player #1 (DAC)";
+			dma-names = "tx";
+			st,uniperiph-id = <2>;
+			st,version = <5>;
+			st,mode = "PCM";
+		};
+
+		sti_uni_player3: sti-uni-player@3 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D85000 0x158>;
+			interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 7 0 1>;
+			dma-names = "tx";
+			dai-name = "Uni Player #1 (PIO)";
+			st,uniperiph-id = <3>;
+			st,version = <5>;
+			st,mode = "SPDIF";
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4
  Cc: peter.griffin-QSEj5FYQhm4dnm+yROfE0A,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA

This patch adds the DT nodes for the uniperif player
IP blocks found on STiH407 family silicon.

Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 60f95b6..7ca149b 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -755,5 +755,81 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spdif_out >;
 		};
+
+		sti_uni_player0: sti-uni-player@0 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D80000 0x158>;
+			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 2 0 1>;
+			dai-name = "Uni Player #0 (HDMI)";
+			dma-names = "tx";
+			st,uniperiph-id = <0>;
+			st,version = <5>;
+			st,mode = "HDMI";
+		};
+
+		sti_uni_player1: sti-uni-player@1 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D81000 0x158>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 3 0 1>;
+			dai-name = "Uni Player #1 (PIO)";
+			dma-names = "tx";
+			st,uniperiph-id = <1>;
+			st,version = <5>;
+			st,mode = "PCM";
+		};
+
+		sti_uni_player2: sti-uni-player@2 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D82000 0x158>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 4 0 1>;
+			dai-name = "Uni Player #1 (DAC)";
+			dma-names = "tx";
+			st,uniperiph-id = <2>;
+			st,version = <5>;
+			st,mode = "PCM";
+		};
+
+		sti_uni_player3: sti-uni-player@3 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D85000 0x158>;
+			interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 7 0 1>;
+			dma-names = "tx";
+			dai-name = "Uni Player #1 (PIO)";
+			st,uniperiph-id = <3>;
+			st,version = <5>;
+			st,mode = "SPDIF";
+		};
 	};
 };
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the DT nodes for the uniperif player
IP blocks found on STiH407 family silicon.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 60f95b6..7ca149b 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -755,5 +755,81 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spdif_out >;
 		};
+
+		sti_uni_player0: sti-uni-player at 0 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D80000 0x158>;
+			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 2 0 1>;
+			dai-name = "Uni Player #0 (HDMI)";
+			dma-names = "tx";
+			st,uniperiph-id = <0>;
+			st,version = <5>;
+			st,mode = "HDMI";
+		};
+
+		sti_uni_player1: sti-uni-player at 1 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D81000 0x158>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 3 0 1>;
+			dai-name = "Uni Player #1 (PIO)";
+			dma-names = "tx";
+			st,uniperiph-id = <1>;
+			st,version = <5>;
+			st,mode = "PCM";
+		};
+
+		sti_uni_player2: sti-uni-player at 2 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D82000 0x158>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 4 0 1>;
+			dai-name = "Uni Player #1 (DAC)";
+			dma-names = "tx";
+			st,uniperiph-id = <2>;
+			st,version = <5>;
+			st,mode = "PCM";
+		};
+
+		sti_uni_player3: sti-uni-player at 3 {
+			compatible = "st,sti-uni-player";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
+			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
+			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
+			assigned-clock-rates = <50000000>;
+			reg = <0x8D85000 0x158>;
+			interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 7 0 1>;
+			dma-names = "tx";
+			dai-name = "Uni Player #1 (PIO)";
+			st,uniperiph-id = <3>;
+			st,version = <5>;
+			st,mode = "SPDIF";
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader dt nodes
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch adds the DT node for the uniperif reader
IP block found on STiH407 family silicon.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 7ca149b..fb6363e1 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -831,5 +831,33 @@
 			st,version = <5>;
 			st,mode = "SPDIF";
 		};
+
+		sti_uni_reader0: sti-uni-reader@0 {
+			compatible = "st,sti-uni-reader";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			reg = <0x8D83000 0x158>;
+			interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 5 0 1>;
+			dma-names = "rx";
+			dai-name = "Uni Reader #0 (PCM IN)";
+			st,version = <3>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2s_8ch_in>;
+		};
+
+		sti_uni_reader1: sti-uni-reader@1 {
+			compatible = "st,sti-uni-reader";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			reg = <0x8D84000 0x158>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 6 0 1>;
+			dma-names = "rx";
+			dai-name = "Uni Reader #1 (HDMI RX)";
+			st,version = <3>;
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader dt nodes
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the DT node for the uniperif reader
IP block found on STiH407 family silicon.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 7ca149b..fb6363e1 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -831,5 +831,33 @@
 			st,version = <5>;
 			st,mode = "SPDIF";
 		};
+
+		sti_uni_reader0: sti-uni-reader at 0 {
+			compatible = "st,sti-uni-reader";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			reg = <0x8D83000 0x158>;
+			interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 5 0 1>;
+			dma-names = "rx";
+			dai-name = "Uni Reader #0 (PCM IN)";
+			st,version = <3>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2s_8ch_in>;
+		};
+
+		sti_uni_reader1: sti-uni-reader at 1 {
+			compatible = "st,sti-uni-reader";
+			status = "disabled";
+			#sound-dai-cells = <0>;
+			st,syscfg = <&syscfg_core>;
+			reg = <0x8D84000 0x158>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
+			dmas = <&fdma0 6 0 1>;
+			dma-names = "rx";
+			dai-name = "Uni Reader #1 (HDMI RX)";
+			st,version = <3>;
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 18/18] ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
  2016-05-25 16:06 ` Peter Griffin
@ 2016-05-25 16:06   ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: peter.griffin, lee.jones, devicetree, dmaengine, linux-remoteproc

This patch enables the uniperif players 2 & 3 for b2120 boards
and also adds the "simple-audio-card" device node to interconnect
the SoC sound device and the codec.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stihxxx-b2120.dtsi | 40 ++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index 722c63f..5297f21 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -131,5 +131,45 @@
 				dvb-card	= <STV0367_TDA18212_NIMA_1>;
 			};
 		};
+
+		sti_uni_player2: sti-uni-player@2 {
+			status = "okay";
+		};
+
+		sti_uni_player3: sti-uni-player@3 {
+			status = "okay";
+		};
+
+		sound {
+			compatible = "simple-audio-card";
+			simple-audio-card,name = "sti audio card";
+			status = "okay";
+
+			simple-audio-card,dai-link@0 {
+				/* DAC */
+				format = "i2s";
+				dai-tdm-slot-width = <32>;
+				mclk-fs = <256>;
+				cpu {
+					sound-dai = <&sti_uni_player2>;
+				};
+
+				codec {
+					sound-dai = <&sti_sasg_codec 1>;
+				};
+			};
+			simple-audio-card,dai-link@1 {
+				/* SPDIF */
+				format = "left_j";
+				mclk-fs = <128>;
+				cpu {
+					sound-dai = <&sti_uni_player3>;
+				};
+
+				codec {
+					sound-dai = <&sti_sasg_codec 0>;
+				};
+			};
+		};
 	};
 };
-- 
1.9.1

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

* [PATCH v4 18/18] ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
@ 2016-05-25 16:06   ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-25 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch enables the uniperif players 2 & 3 for b2120 boards
and also adds the "simple-audio-card" device node to interconnect
the SoC sound device and the codec.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 arch/arm/boot/dts/stihxxx-b2120.dtsi | 40 ++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index 722c63f..5297f21 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -131,5 +131,45 @@
 				dvb-card	= <STV0367_TDA18212_NIMA_1>;
 			};
 		};
+
+		sti_uni_player2: sti-uni-player at 2 {
+			status = "okay";
+		};
+
+		sti_uni_player3: sti-uni-player at 3 {
+			status = "okay";
+		};
+
+		sound {
+			compatible = "simple-audio-card";
+			simple-audio-card,name = "sti audio card";
+			status = "okay";
+
+			simple-audio-card,dai-link at 0 {
+				/* DAC */
+				format = "i2s";
+				dai-tdm-slot-width = <32>;
+				mclk-fs = <256>;
+				cpu {
+					sound-dai = <&sti_uni_player2>;
+				};
+
+				codec {
+					sound-dai = <&sti_sasg_codec 1>;
+				};
+			};
+			simple-audio-card,dai-link at 1 {
+				/* SPDIF */
+				format = "left_j";
+				mclk-fs = <128>;
+				cpu {
+					sound-dai = <&sti_uni_player3>;
+				};
+
+				codec {
+					sound-dai = <&sti_sasg_codec 0>;
+				};
+			};
+		};
 	};
 };
-- 
1.9.1

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

* Re: [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
  2016-05-25 16:06   ` Peter Griffin
@ 2016-05-25 17:10     ` Bjorn Andersson
  -1 siblings, 0 replies; 113+ messages in thread
From: Bjorn Andersson @ 2016-05-25 17:10 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc

On Wed 25 May 09:06 PDT 2016, Peter Griffin wrote:

> XP70 slim core is used as a basis for many IPs in the STi
> chipsets such as fdma, display, and demux. To avoid
> duplicating the elf loading code in each device driver
> an xp70 rproc driver has been created.
> 
I like this approach.

[..]

> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
[..]
>  
> +config ST_XP70_REMOTEPROC
> +	tristate "XP70 slim remoteproc support"

As this "driver" in itself doesn't do anything I don't think it makes
sense to have it user selectable. Please make the "clients" select it
instead.

> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support xp70 slim core.
> +	  If unsure say N.
> +
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
[..]
> +#include <linux/clk.h>
> +#include <linux/elf.h>

You should be able to drop inclusion of elf.h now.

[..]
> +static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
> +{
> +	int clk, err = 0;

No need to initialize err.

> +
> +	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
> +		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
> +		if (IS_ERR(xp70_rproc->clks[clk])) {
> +			err = PTR_ERR(xp70_rproc->clks[clk]);
> +			if (err == -EPROBE_DEFER)
> +				goto err_put_clks;
> +			xp70_rproc->clks[clk] = NULL;
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_put_clks:
> +	while (--clk >= 0)
> +		clk_put(xp70_rproc->clks[clk]);
> +
> +	return err;
> +}
> +
[..]
> +/**
> + * Remoteproc xp70 specific device handlers
> + */
> +static int xp70_rproc_start(struct rproc *rproc)
> +{
> +	struct device *dev = &rproc->dev;
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	unsigned long hw_id, hw_ver, fw_rev;
> +	u32 val, ret = 0;

ret should be signed and there's no need to initialize it.

> +
> +	ret = xp70_clk_enable(xp70_rproc);
> +	if (ret) {
> +		dev_err(dev, "Failed to enable clocks\n");
> +		goto err_clk;
> +	}
[..]
> +
> +	dev_dbg(dev, "XP70 started\n");
> +
> +err_clk:
> +	return ret;
> +}
> +
> +static int xp70_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	u32 val;
> +
> +	/* mask all (cmd & int) channels */
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> +
> +	/* disable cpu pipeline clock */
> +	writel_relaxed(XP70_CLK_GATE_DIS
> +		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);

Don't you want to ensure ordering of these writes? Perhaps making this
last one a writel()?

> +
> +	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
> +	if (val & XP70_EN_RUN)
> +		dev_warn(&rproc->dev, "Failed to disable XP70");
> +
> +	xp70_clk_disable(xp70_rproc);
> +
> +	dev_dbg(&rproc->dev, "xp70 stopped\n");
> +
> +	return 0;
> +}
> +
> +static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	void *va = NULL;
> +	int i;
> +
> +	for (i = 0; i < XP70_MEM_MAX; i++) {
> +
> +		if (da != xp70_rproc->mem[i].bus_addr)
> +			continue;
> +
> +		va = xp70_rproc->mem[i].cpu_addr;
> +			break;
> +	}

Please clean up the indentation and drop the extra newline at the
beginning in this loop.

> +
> +	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
> +		, __func__, da, len, va);
> +
> +	return va;
> +}
> +
> +static struct rproc_ops xp70_rproc_ops = {
> +	.start		= xp70_rproc_start,
> +	.stop		= xp70_rproc_stop,
> +	.da_to_va       = xp70_rproc_da_to_va,
> +};
> +
> +/**
> + * Firmware handler operations: sanity, boot address, load ...
> + */
> +
> +static struct resource_table empty_rsc_tbl = {
> +	.ver = 1,
> +	.num = 0,
> +};


I'm looking at making the resource table optional, good to see another
vote for that. Looks good for now though.

[..]

> +
> +/**
> +  * xp70_rproc_alloc - allocate and initialise xp70 rproc

Drop one of the two spaces indenting this block and add () after then
function name.

> +  * @pdev: Pointer to the platform_device struct
> +  * @fw_name: Name of firmware for rproc to use
> +  *
> +  * Function for allocating and initialising a xp70 rproc for use by
> +  * device drivers whose IP is based around the xp70 slim core. It
> +  * obtains and enables any clocks required by the xp70 core and also
> +  * ioremaps the various IO.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct st_xp70_rproc *xp70_rproc;
> +	struct device_node *np = dev->of_node;
> +	struct rproc *rproc;
> +	struct resource *res;
> +	int err, i;
> +	const struct rproc_fw_ops *elf_ops;
> +
> +	if (!np || !fw_name)
> +		return ERR_PTR(-EINVAL);

This should, I believe, only ever happen in development. So if you want
to keep it to aid developers feel free to throw in a WARN_ON() in the
condition.

> +
> +	if (!of_device_is_compatible(np, "st,xp70-rproc"))
> +		return ERR_PTR(-EINVAL);
> +
> +	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
> +			fw_name, sizeof(*xp70_rproc));
> +	if (!rproc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	rproc->has_iommu = false;
> +
> +	xp70_rproc = rproc->priv;
> +	xp70_rproc->rproc = rproc;
> +
> +	/* Get standard ELF ops */
> +	elf_ops = rproc_get_elf_ops();
> +
> +	/* Use some generic elf ops */
> +	xp70_rproc_fw_ops.load = elf_ops->load;
> +	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
> +
> +	rproc->fw_ops = &xp70_rproc_fw_ops;
> +
> +	/* get imem and dmem */
> +	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
> +		res = xp70_rproc->mem[i].io_res;
> +

io_res is NULL here, and res is directly assigned again. So drop this
and io_res from the struct.

> +		res = platform_get_resource_byname
> +			(pdev, IORESOURCE_MEM, mem_names[i]);
> +
> +		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
> +		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
> +			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
> +			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
> +			goto err;
> +		}
> +		xp70_rproc->mem[i].bus_addr = res->start;
> +		xp70_rproc->mem[i].size = resource_size(res);
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
> +
> +	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->slimcore)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
> +		err = PTR_ERR(xp70_rproc->slimcore);
> +		goto err;
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
> +
> +	xp70_rproc->peri = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->peri)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
> +		err = PTR_ERR(xp70_rproc->peri);
> +		goto err;
> +	}
> +
> +	err = xp70_clk_get(xp70_rproc, dev);
> +	if (err)
> +		goto err;
> +
> +	/* Register as a remoteproc device */
> +	err = rproc_add(rproc);
> +	if (err) {
> +		dev_err(dev, "registration of xp70 remoteproc failed\n");
> +		goto err;

In this case you should also put the clocks.

> +	}
> +
> +	dev_dbg(dev, "XP70 rproc init successful\n");
> +	return rproc;
> +
> +err:
> +	rproc_put(rproc);
> +	return ERR_PTR(err);
> +}
> +EXPORT_SYMBOL(xp70_rproc_alloc);
> +
> +/**
> +  * xp70_rproc_put - put xp70 rproc resources
> +  * @xp70_rproc: Pointer to the st_xp70_rproc struct
> +  *
> +  * Function for calling respective _put() functions on
> +  * xp70_rproc resources.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk;
> +
> +	if (!xp70_rproc)
> +		return;
> +
> +	rproc_put(xp70_rproc->rproc);
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> +		clk_put(xp70_rproc->clks[clk]);

rproc_put() will free your private data, i.e. xp70_rproc, so you must
put your clocks before that.

> +
> +}
> +EXPORT_SYMBOL(xp70_rproc_put);
> +
> +MODULE_AUTHOR("Peter Griffin");
> +MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
[..]
> +
> +#define XP70_MEM_MAX 2
> +#define XP70_MAX_CLK 4
> +#define NAME_SZ 10

NAME_SZ seems unused and would be too generic.

> +
> +enum {
> +	DMEM,
> +	IMEM,

These are too generic for a header file.

> +};
> +
> +/**
> + * struct xp70_mem - xp70 internal memory structure
> + * @cpu_addr: MPU virtual address of the memory region
> + * @bus_addr: Bus address used to access the memory region
> + * @dev_addr: Device address from Wakeup M3 view
> + * @size: Size of the memory region
> + */
> +struct xp70_mem {
> +	void __iomem *cpu_addr;
> +	phys_addr_t bus_addr;
> +	u32 dev_addr;

dev_addr is unused.

> +	size_t size;
> +	struct resource *io_res;

io_res is unused.

> +};
> +
> +/**
> + * struct st_xp70_rproc - XP70 slim core
> + * @rproc: rproc handle
> + * @pdev: pointer to platform device
> + * @mem: xp70 memory information
> + * @slimcore: xp70 slimcore regs
> + * @peri: xp70 peripheral regs
> + * @clks: xp70 clocks
> + */
> +struct st_xp70_rproc {
> +	struct rproc *rproc;
> +	struct platform_device *pdev;

pdev is unused.

> +	struct xp70_mem mem[XP70_MEM_MAX];
> +	void __iomem *slimcore;
> +	void __iomem *peri;
> +	struct clk *clks[XP70_MAX_CLK];
> +};

I generally don't like sharing a struct like this between two
implementations, but I don't think it's worth working around it in this
case.

Perhaps you can group the members into a section of "public" and a
section of "private" members; with a /* st_xp70_rproc private */ heading
the latter?

> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);

For consistency I think xp70_rproc_alloc() should return a st_xp70_rproc
reference, rather than forcing the clients pull that pointer out of
rproc->priv.

> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> +
> +#endif

Regards,
Bjorn

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

* [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-05-25 17:10     ` Bjorn Andersson
  0 siblings, 0 replies; 113+ messages in thread
From: Bjorn Andersson @ 2016-05-25 17:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed 25 May 09:06 PDT 2016, Peter Griffin wrote:

> XP70 slim core is used as a basis for many IPs in the STi
> chipsets such as fdma, display, and demux. To avoid
> duplicating the elf loading code in each device driver
> an xp70 rproc driver has been created.
> 
I like this approach.

[..]

> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
[..]
>  
> +config ST_XP70_REMOTEPROC
> +	tristate "XP70 slim remoteproc support"

As this "driver" in itself doesn't do anything I don't think it makes
sense to have it user selectable. Please make the "clients" select it
instead.

> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support xp70 slim core.
> +	  If unsure say N.
> +
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
[..]
> +#include <linux/clk.h>
> +#include <linux/elf.h>

You should be able to drop inclusion of elf.h now.

[..]
> +static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
> +{
> +	int clk, err = 0;

No need to initialize err.

> +
> +	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
> +		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
> +		if (IS_ERR(xp70_rproc->clks[clk])) {
> +			err = PTR_ERR(xp70_rproc->clks[clk]);
> +			if (err == -EPROBE_DEFER)
> +				goto err_put_clks;
> +			xp70_rproc->clks[clk] = NULL;
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_put_clks:
> +	while (--clk >= 0)
> +		clk_put(xp70_rproc->clks[clk]);
> +
> +	return err;
> +}
> +
[..]
> +/**
> + * Remoteproc xp70 specific device handlers
> + */
> +static int xp70_rproc_start(struct rproc *rproc)
> +{
> +	struct device *dev = &rproc->dev;
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	unsigned long hw_id, hw_ver, fw_rev;
> +	u32 val, ret = 0;

ret should be signed and there's no need to initialize it.

> +
> +	ret = xp70_clk_enable(xp70_rproc);
> +	if (ret) {
> +		dev_err(dev, "Failed to enable clocks\n");
> +		goto err_clk;
> +	}
[..]
> +
> +	dev_dbg(dev, "XP70 started\n");
> +
> +err_clk:
> +	return ret;
> +}
> +
> +static int xp70_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	u32 val;
> +
> +	/* mask all (cmd & int) channels */
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> +
> +	/* disable cpu pipeline clock */
> +	writel_relaxed(XP70_CLK_GATE_DIS
> +		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);

Don't you want to ensure ordering of these writes? Perhaps making this
last one a writel()?

> +
> +	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
> +	if (val & XP70_EN_RUN)
> +		dev_warn(&rproc->dev, "Failed to disable XP70");
> +
> +	xp70_clk_disable(xp70_rproc);
> +
> +	dev_dbg(&rproc->dev, "xp70 stopped\n");
> +
> +	return 0;
> +}
> +
> +static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	void *va = NULL;
> +	int i;
> +
> +	for (i = 0; i < XP70_MEM_MAX; i++) {
> +
> +		if (da != xp70_rproc->mem[i].bus_addr)
> +			continue;
> +
> +		va = xp70_rproc->mem[i].cpu_addr;
> +			break;
> +	}

Please clean up the indentation and drop the extra newline at the
beginning in this loop.

> +
> +	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
> +		, __func__, da, len, va);
> +
> +	return va;
> +}
> +
> +static struct rproc_ops xp70_rproc_ops = {
> +	.start		= xp70_rproc_start,
> +	.stop		= xp70_rproc_stop,
> +	.da_to_va       = xp70_rproc_da_to_va,
> +};
> +
> +/**
> + * Firmware handler operations: sanity, boot address, load ...
> + */
> +
> +static struct resource_table empty_rsc_tbl = {
> +	.ver = 1,
> +	.num = 0,
> +};


I'm looking at making the resource table optional, good to see another
vote for that. Looks good for now though.

[..]

> +
> +/**
> +  * xp70_rproc_alloc - allocate and initialise xp70 rproc

Drop one of the two spaces indenting this block and add () after then
function name.

> +  * @pdev: Pointer to the platform_device struct
> +  * @fw_name: Name of firmware for rproc to use
> +  *
> +  * Function for allocating and initialising a xp70 rproc for use by
> +  * device drivers whose IP is based around the xp70 slim core. It
> +  * obtains and enables any clocks required by the xp70 core and also
> +  * ioremaps the various IO.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct st_xp70_rproc *xp70_rproc;
> +	struct device_node *np = dev->of_node;
> +	struct rproc *rproc;
> +	struct resource *res;
> +	int err, i;
> +	const struct rproc_fw_ops *elf_ops;
> +
> +	if (!np || !fw_name)
> +		return ERR_PTR(-EINVAL);

This should, I believe, only ever happen in development. So if you want
to keep it to aid developers feel free to throw in a WARN_ON() in the
condition.

> +
> +	if (!of_device_is_compatible(np, "st,xp70-rproc"))
> +		return ERR_PTR(-EINVAL);
> +
> +	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
> +			fw_name, sizeof(*xp70_rproc));
> +	if (!rproc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	rproc->has_iommu = false;
> +
> +	xp70_rproc = rproc->priv;
> +	xp70_rproc->rproc = rproc;
> +
> +	/* Get standard ELF ops */
> +	elf_ops = rproc_get_elf_ops();
> +
> +	/* Use some generic elf ops */
> +	xp70_rproc_fw_ops.load = elf_ops->load;
> +	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
> +
> +	rproc->fw_ops = &xp70_rproc_fw_ops;
> +
> +	/* get imem and dmem */
> +	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
> +		res = xp70_rproc->mem[i].io_res;
> +

io_res is NULL here, and res is directly assigned again. So drop this
and io_res from the struct.

> +		res = platform_get_resource_byname
> +			(pdev, IORESOURCE_MEM, mem_names[i]);
> +
> +		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
> +		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
> +			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
> +			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
> +			goto err;
> +		}
> +		xp70_rproc->mem[i].bus_addr = res->start;
> +		xp70_rproc->mem[i].size = resource_size(res);
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
> +
> +	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->slimcore)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
> +		err = PTR_ERR(xp70_rproc->slimcore);
> +		goto err;
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
> +
> +	xp70_rproc->peri = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->peri)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
> +		err = PTR_ERR(xp70_rproc->peri);
> +		goto err;
> +	}
> +
> +	err = xp70_clk_get(xp70_rproc, dev);
> +	if (err)
> +		goto err;
> +
> +	/* Register as a remoteproc device */
> +	err = rproc_add(rproc);
> +	if (err) {
> +		dev_err(dev, "registration of xp70 remoteproc failed\n");
> +		goto err;

In this case you should also put the clocks.

> +	}
> +
> +	dev_dbg(dev, "XP70 rproc init successful\n");
> +	return rproc;
> +
> +err:
> +	rproc_put(rproc);
> +	return ERR_PTR(err);
> +}
> +EXPORT_SYMBOL(xp70_rproc_alloc);
> +
> +/**
> +  * xp70_rproc_put - put xp70 rproc resources
> +  * @xp70_rproc: Pointer to the st_xp70_rproc struct
> +  *
> +  * Function for calling respective _put() functions on
> +  * xp70_rproc resources.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk;
> +
> +	if (!xp70_rproc)
> +		return;
> +
> +	rproc_put(xp70_rproc->rproc);
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> +		clk_put(xp70_rproc->clks[clk]);

rproc_put() will free your private data, i.e. xp70_rproc, so you must
put your clocks before that.

> +
> +}
> +EXPORT_SYMBOL(xp70_rproc_put);
> +
> +MODULE_AUTHOR("Peter Griffin");
> +MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
[..]
> +
> +#define XP70_MEM_MAX 2
> +#define XP70_MAX_CLK 4
> +#define NAME_SZ 10

NAME_SZ seems unused and would be too generic.

> +
> +enum {
> +	DMEM,
> +	IMEM,

These are too generic for a header file.

> +};
> +
> +/**
> + * struct xp70_mem - xp70 internal memory structure
> + * @cpu_addr: MPU virtual address of the memory region
> + * @bus_addr: Bus address used to access the memory region
> + * @dev_addr: Device address from Wakeup M3 view
> + * @size: Size of the memory region
> + */
> +struct xp70_mem {
> +	void __iomem *cpu_addr;
> +	phys_addr_t bus_addr;
> +	u32 dev_addr;

dev_addr is unused.

> +	size_t size;
> +	struct resource *io_res;

io_res is unused.

> +};
> +
> +/**
> + * struct st_xp70_rproc - XP70 slim core
> + * @rproc: rproc handle
> + * @pdev: pointer to platform device
> + * @mem: xp70 memory information
> + * @slimcore: xp70 slimcore regs
> + * @peri: xp70 peripheral regs
> + * @clks: xp70 clocks
> + */
> +struct st_xp70_rproc {
> +	struct rproc *rproc;
> +	struct platform_device *pdev;

pdev is unused.

> +	struct xp70_mem mem[XP70_MEM_MAX];
> +	void __iomem *slimcore;
> +	void __iomem *peri;
> +	struct clk *clks[XP70_MAX_CLK];
> +};

I generally don't like sharing a struct like this between two
implementations, but I don't think it's worth working around it in this
case.

Perhaps you can group the members into a section of "public" and a
section of "private" members; with a /* st_xp70_rproc private */ heading
the latter?

> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);

For consistency I think xp70_rproc_alloc() should return a st_xp70_rproc
reference, rather than forcing the clients pull that pointer out of
rproc->priv.

> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> +
> +#endif

Regards,
Bjorn

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

* Re: [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
  2016-05-25 16:06   ` Peter Griffin
@ 2016-05-25 17:27     ` Bjorn Andersson
  -1 siblings, 0 replies; 113+ messages in thread
From: Bjorn Andersson @ 2016-05-25 17:27 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc,
	Ludovic Barre

On Wed 25 May 09:06 PDT 2016, Peter Griffin wrote:

> diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
[..]
> +
> +static int st_fdma_alloc_chan_res(struct dma_chan *chan)
> +{
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	int ret;
> +
> +	/* Create the dma pool for descriptor allocation */
> +	fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device),
> +					    fchan->fdev->dev,
> +					    sizeof(struct st_fdma_hw_node),
> +					    __alignof__(struct st_fdma_hw_node),
> +					    0);
> +
> +	if (!fchan->node_pool) {
> +		dev_err(fchan->fdev->dev, "unable to allocate desc pool\n");
> +		return -ENOMEM;
> +	}
> +
> +
> +	ret = rproc_boot(fchan->fdev->rproc);
> +	if (ret) {
> +		dev_err(fchan->fdev->dev, "rproc_boot failed\n");

rproc_boot(), rproc_fw_boot() and xp70_rproc_start() has already given
you specific error messages; drop this generic message.

Don't you want to destroy the dma_pool if this happens?

> +		return ret;
> +	}
> +
> +	dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n",
> +		fchan->vchan.chan.chan_id, fchan->cfg.type);
> +
> +	return 0;
> +}
> +
[..]
> +
> +static const struct st_fdma_driverdata fdma_mpe31_stih407_11 = {
> +	.name = "STiH407",
> +	.id = 0,
> +};
> +
> +static const struct st_fdma_driverdata fdma_mpe31_stih407_12 = {
> +	.name = "STiH407",
> +	.id = 1,
> +};
> +
> +static const struct st_fdma_driverdata fdma_mpe31_stih407_13 = {
> +	.name = "STiH407",
> +	.id = 2,
> +};
> +
> +static const struct of_device_id st_fdma_match[] = {
> +	{ .compatible = "st,stih407-fdma-mpe31-11"
> +	  , .data = &fdma_mpe31_stih407_11 },
> +	{ .compatible = "st,stih407-fdma-mpe31-12"
> +	  , .data = &fdma_mpe31_stih407_12 },
> +	{ .compatible = "st,stih407-fdma-mpe31-13"
> +	  , .data = &fdma_mpe31_stih407_13 },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, st_fdma_match);
> +
> +static int st_fdma_parse_dt(struct platform_device *pdev,
> +			const struct st_fdma_driverdata *drvdata,
> +			struct st_fdma_dev *fdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	int ret;
> +
> +	if (!np)
> +		goto err;

ret is left uninitialized here. Also as no error handling is done, just
return your error directly.

> +
> +	ret = of_property_read_u32(np, "dma-channels", &fdev->nr_channels);
> +	if (ret)
> +		goto err;
> +
> +	snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf",
> +		drvdata->name, drvdata->id);
> +
> +err:
> +	return ret;
> +}
> +#define FDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
> +				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
> +				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
> +				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
> +
> +static int st_fdma_probe(struct platform_device *pdev)
> +{
> +	struct st_fdma_dev *fdev;
> +	const struct of_device_id *match;
> +	struct device_node *np = pdev->dev.of_node;
> +	const struct st_fdma_driverdata *drvdata;
> +	int ret, i;
> +
> +	match = of_match_device((st_fdma_match), &pdev->dev);
> +	if (!match || !match->data) {
> +		dev_err(&pdev->dev, "No device match found\n");
> +		return -ENODEV;
> +	}
> +
> +	drvdata = match->data;

Use of_device_get_match_data() instead. This also allows you to keep the
of_match_table and driverdata at the end of the file.

[..]
> +
> +	fdev->rproc = xp70_rproc_alloc(pdev, fdev->fw_name);
> +	if (!fdev->rproc) {
> +		dev_err(&pdev->dev, "xp70_rproc_init failed\n");

All (non-development) error paths in xp70_rproc_alloc() will have
already printed a more specific error message, so no need to print
another generic on here.

> +		ret = PTR_ERR(fdev->rproc);
> +		goto err;
> +	}
> +

Regards,
Bjorn

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

* [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
@ 2016-05-25 17:27     ` Bjorn Andersson
  0 siblings, 0 replies; 113+ messages in thread
From: Bjorn Andersson @ 2016-05-25 17:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed 25 May 09:06 PDT 2016, Peter Griffin wrote:

> diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
[..]
> +
> +static int st_fdma_alloc_chan_res(struct dma_chan *chan)
> +{
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	int ret;
> +
> +	/* Create the dma pool for descriptor allocation */
> +	fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device),
> +					    fchan->fdev->dev,
> +					    sizeof(struct st_fdma_hw_node),
> +					    __alignof__(struct st_fdma_hw_node),
> +					    0);
> +
> +	if (!fchan->node_pool) {
> +		dev_err(fchan->fdev->dev, "unable to allocate desc pool\n");
> +		return -ENOMEM;
> +	}
> +
> +
> +	ret = rproc_boot(fchan->fdev->rproc);
> +	if (ret) {
> +		dev_err(fchan->fdev->dev, "rproc_boot failed\n");

rproc_boot(), rproc_fw_boot() and xp70_rproc_start() has already given
you specific error messages; drop this generic message.

Don't you want to destroy the dma_pool if this happens?

> +		return ret;
> +	}
> +
> +	dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n",
> +		fchan->vchan.chan.chan_id, fchan->cfg.type);
> +
> +	return 0;
> +}
> +
[..]
> +
> +static const struct st_fdma_driverdata fdma_mpe31_stih407_11 = {
> +	.name = "STiH407",
> +	.id = 0,
> +};
> +
> +static const struct st_fdma_driverdata fdma_mpe31_stih407_12 = {
> +	.name = "STiH407",
> +	.id = 1,
> +};
> +
> +static const struct st_fdma_driverdata fdma_mpe31_stih407_13 = {
> +	.name = "STiH407",
> +	.id = 2,
> +};
> +
> +static const struct of_device_id st_fdma_match[] = {
> +	{ .compatible = "st,stih407-fdma-mpe31-11"
> +	  , .data = &fdma_mpe31_stih407_11 },
> +	{ .compatible = "st,stih407-fdma-mpe31-12"
> +	  , .data = &fdma_mpe31_stih407_12 },
> +	{ .compatible = "st,stih407-fdma-mpe31-13"
> +	  , .data = &fdma_mpe31_stih407_13 },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, st_fdma_match);
> +
> +static int st_fdma_parse_dt(struct platform_device *pdev,
> +			const struct st_fdma_driverdata *drvdata,
> +			struct st_fdma_dev *fdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	int ret;
> +
> +	if (!np)
> +		goto err;

ret is left uninitialized here. Also as no error handling is done, just
return your error directly.

> +
> +	ret = of_property_read_u32(np, "dma-channels", &fdev->nr_channels);
> +	if (ret)
> +		goto err;
> +
> +	snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf",
> +		drvdata->name, drvdata->id);
> +
> +err:
> +	return ret;
> +}
> +#define FDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
> +				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
> +				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
> +				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
> +
> +static int st_fdma_probe(struct platform_device *pdev)
> +{
> +	struct st_fdma_dev *fdev;
> +	const struct of_device_id *match;
> +	struct device_node *np = pdev->dev.of_node;
> +	const struct st_fdma_driverdata *drvdata;
> +	int ret, i;
> +
> +	match = of_match_device((st_fdma_match), &pdev->dev);
> +	if (!match || !match->data) {
> +		dev_err(&pdev->dev, "No device match found\n");
> +		return -ENODEV;
> +	}
> +
> +	drvdata = match->data;

Use of_device_get_match_data() instead. This also allows you to keep the
of_match_table and driverdata at the end of the file.

[..]
> +
> +	fdev->rproc = xp70_rproc_alloc(pdev, fdev->fw_name);
> +	if (!fdev->rproc) {
> +		dev_err(&pdev->dev, "xp70_rproc_init failed\n");

All (non-development) error paths in xp70_rproc_alloc() will have
already printed a more specific error message, so no need to print
another generic on here.

> +		ret = PTR_ERR(fdev->rproc);
> +		goto err;
> +	}
> +

Regards,
Bjorn

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

* Re: [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
  2016-05-25 16:06   ` Peter Griffin
  (?)
@ 2016-05-27 13:15     ` Patrice Chotard
  -1 siblings, 0 replies; 113+ messages in thread
From: Patrice Chotard @ 2016-05-27 13:15 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> XP70 slim core is used as a basis for many IPs in the STi
> chipsets such as fdma, display, and demux. To avoid
> duplicating the elf loading code in each device driver
> an xp70 rproc driver has been created.
>
> This driver is designed to be used by other device drivers
> such as fdma, or demux whose IP is based around a xp70 slimcore.
> The device driver can call xp70_rproc_alloc() to allocate
> an xp70 rproc and xp70_rproc_put() when finished.
>
> This driver takes care of ioremapping the xp70
> registers (dmem, imem, slimcore, peripherals), whose offsets
> and sizes can change between IP's. It also obtains and enables
> any clocks used by the device. This approach avoids having
> a double mapping of the registers as xp70_rproc does not register
> its own platform device. It also maps well to device tree
> abstraction as it allows us to have one dt node for the whole
> device.
>
> All of the generic rproc elf loading code can be reused, and
> we provide start() stop() hooks to start and stop the xp70
> core once the firmware has been loaded. This has been tested
> successfully with fdma driver.
>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>   drivers/remoteproc/Kconfig               |   8 +
>   drivers/remoteproc/Makefile              |   1 +
>   drivers/remoteproc/st_xp70_rproc.c       | 380 +++++++++++++++++++++++++++++++
>   include/linux/remoteproc/st_xp70_rproc.h |  56 +++++
>   4 files changed, 445 insertions(+)
>   create mode 100644 drivers/remoteproc/st_xp70_rproc.c
>   create mode 100644 include/linux/remoteproc/st_xp70_rproc.h
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 72e97d7..9e48fd1 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -86,4 +86,12 @@ config ST_REMOTEPROC
>   	  processor framework.
>   	  This can be either built-in or a loadable module.
>   
> +config ST_XP70_REMOTEPROC
> +	tristate "XP70 slim remoteproc support"
> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support xp70 slim core.
> +	  If unsure say N.
> +
>   endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 279cb2e..b5dab8e 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -12,3 +12,4 @@ obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
>   obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
>   obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
>   obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
> +obj-$(CONFIG_ST_XP70_REMOTEPROC)	+= st_xp70_rproc.o
> diff --git a/drivers/remoteproc/st_xp70_rproc.c b/drivers/remoteproc/st_xp70_rproc.c
> new file mode 100644
> index 0000000..6a78e7c
> --- /dev/null
> +++ b/drivers/remoteproc/st_xp70_rproc.c
> @@ -0,0 +1,380 @@
> +/*
> + * st_xp70_rproc.c
> + *
> + * Copyright (C) 2016 STMicroelectronics
> + * Author: Peter Griffin <peter.griffin@st.com>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/elf.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/remoteproc.h>
> +#include <linux/remoteproc/st_xp70_rproc.h>
> +#include "remoteproc_internal.h"
> +
> +/* slimcore registers */
> +#define XP70_ID_OFST		0x0
> +#define XP70_VER_OFST		0x4
> +
> +#define XP70_EN_OFST		0x8
> +#define XP70_EN_RUN			BIT(0)
> +
> +#define XP70_CLK_GATE_OFST	0xC
> +#define XP70_CLK_GATE_DIS		BIT(0)
> +#define XP70_CLK_GATE_RESET		BIT(2)
> +
> +#define XP70_SLIM_PC_OFST	0x20
> +
> +/* dmem registers */
> +#define XP70_REV_ID_OFST	0x0
> +#define XP70_REV_ID_MIN_MASK		GENMASK(15, 8)
> +#define XP70_REV_ID_MIN(id)		((id & XP70_REV_ID_MIN_MASK) >> 8)
> +#define XP70_REV_ID_MAJ_MASK		GENMASK(23, 16)
> +#define XP70_REV_ID_MAJ(id)		((id & XP70_REV_ID_MAJ_MASK) >> 16)
> +
> +
> +/* peripherals registers */
> +#define XP70_STBUS_SYNC_OFST	0xF88
> +#define XP70_STBUS_SYNC_DIS		BIT(0)
> +
> +#define XP70_INT_SET_OFST	0xFD4
> +#define XP70_INT_CLR_OFST	0xFD8
> +#define XP70_INT_MASK_OFST	0xFDC
> +
> +#define XP70_CMD_CLR_OFST	0xFC8
> +#define XP70_CMD_MASK_OFST	0xFCC
> +
> +const char *mem_names[XP70_MEM_MAX] = {
> +	[DMEM]		= "dmem",
> +	[IMEM]		= "imem",
> +};
> +
> +static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
> +{
> +	int clk, err = 0;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
> +		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
> +		if (IS_ERR(xp70_rproc->clks[clk])) {
> +			err = PTR_ERR(xp70_rproc->clks[clk]);
> +			if (err == -EPROBE_DEFER)
> +				goto err_put_clks;
> +			xp70_rproc->clks[clk] = NULL;
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_put_clks:
> +	while (--clk >= 0)
> +		clk_put(xp70_rproc->clks[clk]);
> +
> +	return err;
> +}
> +
> +static void xp70_clk_disable(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> +		clk_disable_unprepare(xp70_rproc->clks[clk]);
> +}
> +
> +static int xp70_clk_enable(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk, ret;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++) {
> +		ret = clk_prepare_enable(xp70_rproc->clks[clk]);
> +		if (ret)
> +			goto err_disable_clks;
> +	}
> +
> +	return 0;
> +
> +err_disable_clks:
> +	while (--clk >= 0)
> +		clk_disable_unprepare(xp70_rproc->clks[clk]);
> +
> +	return ret;
> +}
> +
> +/**
> + * Remoteproc xp70 specific device handlers
> + */
> +static int xp70_rproc_start(struct rproc *rproc)
> +{
> +	struct device *dev = &rproc->dev;
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	unsigned long hw_id, hw_ver, fw_rev;
> +	u32 val, ret = 0;
> +
> +	ret = xp70_clk_enable(xp70_rproc);
> +	if (ret) {
> +		dev_err(dev, "Failed to enable clocks\n");
> +		goto err_clk;
> +	}
> +
> +	/* disable CPU pipeline clock & reset cpu pipeline */
> +	val = XP70_CLK_GATE_DIS | XP70_CLK_GATE_RESET;
> +	writel_relaxed(val, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	/* disable SLIM core STBus sync */
> +	writel_relaxed(XP70_STBUS_SYNC_DIS,
> +		xp70_rproc->peri + XP70_STBUS_SYNC_OFST);
> +
> +	/* enable cpu pipeline clock */
> +	writel_relaxed(!XP70_CLK_GATE_DIS,
> +		xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	/* clear int & cmd mailbox */
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_CLR_OFST);
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_CLR_OFST);
> +
> +	/* enable all channels cmd & int */
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> +
> +	/* enable cpu */
> +	writel(XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
> +
> +	hw_id = readl_relaxed(xp70_rproc->slimcore + XP70_ID_OFST);
> +	hw_ver = readl_relaxed(xp70_rproc->slimcore + XP70_VER_OFST);
> +
> +	fw_rev = readl_relaxed(xp70_rproc->mem[DMEM].cpu_addr +
> +			XP70_REV_ID_OFST);
> +
> +	dev_info(dev, "fw rev:%ld.%ld on SLIM %ld.%ld\n",
> +		 XP70_REV_ID_MAJ(fw_rev), XP70_REV_ID_MIN(fw_rev),
> +		 hw_id, hw_ver);
> +
> +	dev_dbg(dev, "XP70 started\n");
> +
> +err_clk:
> +	return ret;
> +}
> +
> +static int xp70_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	u32 val;
> +
> +	/* mask all (cmd & int) channels */
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> +
> +	/* disable cpu pipeline clock */
> +	writel_relaxed(XP70_CLK_GATE_DIS
> +		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
> +
> +	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
> +	if (val & XP70_EN_RUN)
> +		dev_warn(&rproc->dev, "Failed to disable XP70");
> +
> +	xp70_clk_disable(xp70_rproc);
> +
> +	dev_dbg(&rproc->dev, "xp70 stopped\n");
> +
> +	return 0;
> +}
> +
> +static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	void *va = NULL;
> +	int i;
> +
> +	for (i = 0; i < XP70_MEM_MAX; i++) {
> +
> +		if (da != xp70_rproc->mem[i].bus_addr)
> +			continue;
> +
> +		va = xp70_rproc->mem[i].cpu_addr;
> +			break;
> +	}
> +
> +	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
> +		, __func__, da, len, va);
> +
> +	return va;
> +}
> +
> +static struct rproc_ops xp70_rproc_ops = {
> +	.start		= xp70_rproc_start,
> +	.stop		= xp70_rproc_stop,
> +	.da_to_va       = xp70_rproc_da_to_va,
> +};
> +
> +/**
> + * Firmware handler operations: sanity, boot address, load ...
> + */
> +
> +static struct resource_table empty_rsc_tbl = {
> +	.ver = 1,
> +	.num = 0,
> +};
> +
> +static struct resource_table *xp70_rproc_find_rsc_table(struct rproc *rproc,
> +					       const struct firmware *fw,
> +					       int *tablesz)
> +{
> +	if (!fw)
> +		return NULL;
> +
> +	*tablesz = sizeof(empty_rsc_tbl);
> +	return &empty_rsc_tbl;
> +}
> +
> +static struct resource_table *xp70_rproc_find_loaded_rsc_table(struct rproc *rproc,
> +						      const struct firmware *fw)
> +{
> +	if (!fw)
> +		return NULL;
> +
> +	return &empty_rsc_tbl;
> +}
> +
> +static struct rproc_fw_ops xp70_rproc_fw_ops = {
> +	.find_rsc_table = xp70_rproc_find_rsc_table,
> +	.find_loaded_rsc_table = xp70_rproc_find_loaded_rsc_table,
> +};
> +
> +/**
> +  * xp70_rproc_alloc - allocate and initialise xp70 rproc
> +  * @pdev: Pointer to the platform_device struct
> +  * @fw_name: Name of firmware for rproc to use
> +  *
> +  * Function for allocating and initialising a xp70 rproc for use by
> +  * device drivers whose IP is based around the xp70 slim core. It
> +  * obtains and enables any clocks required by the xp70 core and also
> +  * ioremaps the various IO.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct st_xp70_rproc *xp70_rproc;
> +	struct device_node *np = dev->of_node;
> +	struct rproc *rproc;
> +	struct resource *res;
> +	int err, i;
> +	const struct rproc_fw_ops *elf_ops;
> +
> +	if (!np || !fw_name)
> +		return ERR_PTR(-EINVAL);
> +
> +	if (!of_device_is_compatible(np, "st,xp70-rproc"))
> +		return ERR_PTR(-EINVAL);
> +
> +	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
> +			fw_name, sizeof(*xp70_rproc));
> +	if (!rproc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	rproc->has_iommu = false;
> +
> +	xp70_rproc = rproc->priv;
> +	xp70_rproc->rproc = rproc;
> +
> +	/* Get standard ELF ops */
> +	elf_ops = rproc_get_elf_ops();
> +
> +	/* Use some generic elf ops */
> +	xp70_rproc_fw_ops.load = elf_ops->load;
> +	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
> +
> +	rproc->fw_ops = &xp70_rproc_fw_ops;
> +
> +	/* get imem and dmem */
> +	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
> +		res = xp70_rproc->mem[i].io_res;
> +
> +		res = platform_get_resource_byname
> +			(pdev, IORESOURCE_MEM, mem_names[i]);
> +
> +		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
> +		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
> +			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
> +			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
> +			goto err;
> +		}
> +		xp70_rproc->mem[i].bus_addr = res->start;
> +		xp70_rproc->mem[i].size = resource_size(res);
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
> +
> +	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->slimcore)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
> +		err = PTR_ERR(xp70_rproc->slimcore);
> +		goto err;
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
> +
> +	xp70_rproc->peri = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->peri)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
> +		err = PTR_ERR(xp70_rproc->peri);
> +		goto err;
> +	}
> +
> +	err = xp70_clk_get(xp70_rproc, dev);
> +	if (err)
> +		goto err;
> +
> +	/* Register as a remoteproc device */
> +	err = rproc_add(rproc);
> +	if (err) {
> +		dev_err(dev, "registration of xp70 remoteproc failed\n");
> +		goto err;
> +	}
> +
> +	dev_dbg(dev, "XP70 rproc init successful\n");
> +	return rproc;
> +
> +err:
> +	rproc_put(rproc);
> +	return ERR_PTR(err);
> +}
> +EXPORT_SYMBOL(xp70_rproc_alloc);
> +
> +/**
> +  * xp70_rproc_put - put xp70 rproc resources
> +  * @xp70_rproc: Pointer to the st_xp70_rproc struct
> +  *
> +  * Function for calling respective _put() functions on
> +  * xp70_rproc resources.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk;
> +
> +	if (!xp70_rproc)
> +		return;
> +
> +	rproc_put(xp70_rproc->rproc);
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> +		clk_put(xp70_rproc->clks[clk]);
> +
> +}
> +EXPORT_SYMBOL(xp70_rproc_put);
> +
> +MODULE_AUTHOR("Peter Griffin");
> +MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
> new file mode 100644
> index 0000000..3aba2de
> --- /dev/null
> +++ b/include/linux/remoteproc/st_xp70_rproc.h
> @@ -0,0 +1,56 @@
> +/*
> + * st_xp70_rproc.h
> + *
> + * Copyright (C) 2016 STMicroelectronics
> + * Author: Peter Griffin <peter.griffin@linaro.org>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +#ifndef _ST_XP70_H
> +#define _ST_XP70_H
> +
> +#define XP70_MEM_MAX 2
> +#define XP70_MAX_CLK 4
> +#define NAME_SZ 10
> +
> +enum {
> +	DMEM,
> +	IMEM,
> +};
> +
> +/**
> + * struct xp70_mem - xp70 internal memory structure
> + * @cpu_addr: MPU virtual address of the memory region
> + * @bus_addr: Bus address used to access the memory region
> + * @dev_addr: Device address from Wakeup M3 view
> + * @size: Size of the memory region
> + */
> +struct xp70_mem {
> +	void __iomem *cpu_addr;
> +	phys_addr_t bus_addr;
> +	u32 dev_addr;
> +	size_t size;
> +	struct resource *io_res;
> +};
> +
> +/**
> + * struct st_xp70_rproc - XP70 slim core
> + * @rproc: rproc handle
> + * @pdev: pointer to platform device
> + * @mem: xp70 memory information
> + * @slimcore: xp70 slimcore regs
> + * @peri: xp70 peripheral regs
> + * @clks: xp70 clocks
> + */
> +struct st_xp70_rproc {
> +	struct rproc *rproc;
> +	struct platform_device *pdev;
> +	struct xp70_mem mem[XP70_MEM_MAX];
> +	void __iomem *slimcore;
> +	void __iomem *peri;
> +	struct clk *clks[XP70_MAX_CLK];
> +};
> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> +
> +#endif

Hi Peter

Applying this series on top of v4.6 kernel leads to the following 
compilation error due to patch 01/18 :

drivers/remoteproc/st_xp70_rproc.c: In function 'xp70_rproc_alloc':
drivers/remoteproc/st_xp70_rproc.c:291:2: error: implicit declaration of 
function 'rproc_get_elf_ops' [-Werror=implicit-function-declaration]
   elf_ops = rproc_get_elf_ops();
   ^
   LD [M]  drivers/remoteproc/remoteproc.o


Patrice

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

* Re: [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-05-27 13:15     ` Patrice Chotard
  0 siblings, 0 replies; 113+ messages in thread
From: Patrice Chotard @ 2016-05-27 13:15 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, vinod.koul, ohad,
	bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> XP70 slim core is used as a basis for many IPs in the STi
> chipsets such as fdma, display, and demux. To avoid
> duplicating the elf loading code in each device driver
> an xp70 rproc driver has been created.
>
> This driver is designed to be used by other device drivers
> such as fdma, or demux whose IP is based around a xp70 slimcore.
> The device driver can call xp70_rproc_alloc() to allocate
> an xp70 rproc and xp70_rproc_put() when finished.
>
> This driver takes care of ioremapping the xp70
> registers (dmem, imem, slimcore, peripherals), whose offsets
> and sizes can change between IP's. It also obtains and enables
> any clocks used by the device. This approach avoids having
> a double mapping of the registers as xp70_rproc does not register
> its own platform device. It also maps well to device tree
> abstraction as it allows us to have one dt node for the whole
> device.
>
> All of the generic rproc elf loading code can be reused, and
> we provide start() stop() hooks to start and stop the xp70
> core once the firmware has been loaded. This has been tested
> successfully with fdma driver.
>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>   drivers/remoteproc/Kconfig               |   8 +
>   drivers/remoteproc/Makefile              |   1 +
>   drivers/remoteproc/st_xp70_rproc.c       | 380 +++++++++++++++++++++++++++++++
>   include/linux/remoteproc/st_xp70_rproc.h |  56 +++++
>   4 files changed, 445 insertions(+)
>   create mode 100644 drivers/remoteproc/st_xp70_rproc.c
>   create mode 100644 include/linux/remoteproc/st_xp70_rproc.h
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 72e97d7..9e48fd1 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -86,4 +86,12 @@ config ST_REMOTEPROC
>   	  processor framework.
>   	  This can be either built-in or a loadable module.
>   
> +config ST_XP70_REMOTEPROC
> +	tristate "XP70 slim remoteproc support"
> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support xp70 slim core.
> +	  If unsure say N.
> +
>   endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 279cb2e..b5dab8e 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -12,3 +12,4 @@ obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
>   obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
>   obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
>   obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
> +obj-$(CONFIG_ST_XP70_REMOTEPROC)	+= st_xp70_rproc.o
> diff --git a/drivers/remoteproc/st_xp70_rproc.c b/drivers/remoteproc/st_xp70_rproc.c
> new file mode 100644
> index 0000000..6a78e7c
> --- /dev/null
> +++ b/drivers/remoteproc/st_xp70_rproc.c
> @@ -0,0 +1,380 @@
> +/*
> + * st_xp70_rproc.c
> + *
> + * Copyright (C) 2016 STMicroelectronics
> + * Author: Peter Griffin <peter.griffin@st.com>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/elf.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/remoteproc.h>
> +#include <linux/remoteproc/st_xp70_rproc.h>
> +#include "remoteproc_internal.h"
> +
> +/* slimcore registers */
> +#define XP70_ID_OFST		0x0
> +#define XP70_VER_OFST		0x4
> +
> +#define XP70_EN_OFST		0x8
> +#define XP70_EN_RUN			BIT(0)
> +
> +#define XP70_CLK_GATE_OFST	0xC
> +#define XP70_CLK_GATE_DIS		BIT(0)
> +#define XP70_CLK_GATE_RESET		BIT(2)
> +
> +#define XP70_SLIM_PC_OFST	0x20
> +
> +/* dmem registers */
> +#define XP70_REV_ID_OFST	0x0
> +#define XP70_REV_ID_MIN_MASK		GENMASK(15, 8)
> +#define XP70_REV_ID_MIN(id)		((id & XP70_REV_ID_MIN_MASK) >> 8)
> +#define XP70_REV_ID_MAJ_MASK		GENMASK(23, 16)
> +#define XP70_REV_ID_MAJ(id)		((id & XP70_REV_ID_MAJ_MASK) >> 16)
> +
> +
> +/* peripherals registers */
> +#define XP70_STBUS_SYNC_OFST	0xF88
> +#define XP70_STBUS_SYNC_DIS		BIT(0)
> +
> +#define XP70_INT_SET_OFST	0xFD4
> +#define XP70_INT_CLR_OFST	0xFD8
> +#define XP70_INT_MASK_OFST	0xFDC
> +
> +#define XP70_CMD_CLR_OFST	0xFC8
> +#define XP70_CMD_MASK_OFST	0xFCC
> +
> +const char *mem_names[XP70_MEM_MAX] = {
> +	[DMEM]		= "dmem",
> +	[IMEM]		= "imem",
> +};
> +
> +static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
> +{
> +	int clk, err = 0;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
> +		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
> +		if (IS_ERR(xp70_rproc->clks[clk])) {
> +			err = PTR_ERR(xp70_rproc->clks[clk]);
> +			if (err == -EPROBE_DEFER)
> +				goto err_put_clks;
> +			xp70_rproc->clks[clk] = NULL;
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_put_clks:
> +	while (--clk >= 0)
> +		clk_put(xp70_rproc->clks[clk]);
> +
> +	return err;
> +}
> +
> +static void xp70_clk_disable(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> +		clk_disable_unprepare(xp70_rproc->clks[clk]);
> +}
> +
> +static int xp70_clk_enable(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk, ret;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++) {
> +		ret = clk_prepare_enable(xp70_rproc->clks[clk]);
> +		if (ret)
> +			goto err_disable_clks;
> +	}
> +
> +	return 0;
> +
> +err_disable_clks:
> +	while (--clk >= 0)
> +		clk_disable_unprepare(xp70_rproc->clks[clk]);
> +
> +	return ret;
> +}
> +
> +/**
> + * Remoteproc xp70 specific device handlers
> + */
> +static int xp70_rproc_start(struct rproc *rproc)
> +{
> +	struct device *dev = &rproc->dev;
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	unsigned long hw_id, hw_ver, fw_rev;
> +	u32 val, ret = 0;
> +
> +	ret = xp70_clk_enable(xp70_rproc);
> +	if (ret) {
> +		dev_err(dev, "Failed to enable clocks\n");
> +		goto err_clk;
> +	}
> +
> +	/* disable CPU pipeline clock & reset cpu pipeline */
> +	val = XP70_CLK_GATE_DIS | XP70_CLK_GATE_RESET;
> +	writel_relaxed(val, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	/* disable SLIM core STBus sync */
> +	writel_relaxed(XP70_STBUS_SYNC_DIS,
> +		xp70_rproc->peri + XP70_STBUS_SYNC_OFST);
> +
> +	/* enable cpu pipeline clock */
> +	writel_relaxed(!XP70_CLK_GATE_DIS,
> +		xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	/* clear int & cmd mailbox */
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_CLR_OFST);
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_CLR_OFST);
> +
> +	/* enable all channels cmd & int */
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> +
> +	/* enable cpu */
> +	writel(XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
> +
> +	hw_id = readl_relaxed(xp70_rproc->slimcore + XP70_ID_OFST);
> +	hw_ver = readl_relaxed(xp70_rproc->slimcore + XP70_VER_OFST);
> +
> +	fw_rev = readl_relaxed(xp70_rproc->mem[DMEM].cpu_addr +
> +			XP70_REV_ID_OFST);
> +
> +	dev_info(dev, "fw rev:%ld.%ld on SLIM %ld.%ld\n",
> +		 XP70_REV_ID_MAJ(fw_rev), XP70_REV_ID_MIN(fw_rev),
> +		 hw_id, hw_ver);
> +
> +	dev_dbg(dev, "XP70 started\n");
> +
> +err_clk:
> +	return ret;
> +}
> +
> +static int xp70_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	u32 val;
> +
> +	/* mask all (cmd & int) channels */
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> +
> +	/* disable cpu pipeline clock */
> +	writel_relaxed(XP70_CLK_GATE_DIS
> +		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
> +
> +	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
> +	if (val & XP70_EN_RUN)
> +		dev_warn(&rproc->dev, "Failed to disable XP70");
> +
> +	xp70_clk_disable(xp70_rproc);
> +
> +	dev_dbg(&rproc->dev, "xp70 stopped\n");
> +
> +	return 0;
> +}
> +
> +static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	void *va = NULL;
> +	int i;
> +
> +	for (i = 0; i < XP70_MEM_MAX; i++) {
> +
> +		if (da != xp70_rproc->mem[i].bus_addr)
> +			continue;
> +
> +		va = xp70_rproc->mem[i].cpu_addr;
> +			break;
> +	}
> +
> +	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
> +		, __func__, da, len, va);
> +
> +	return va;
> +}
> +
> +static struct rproc_ops xp70_rproc_ops = {
> +	.start		= xp70_rproc_start,
> +	.stop		= xp70_rproc_stop,
> +	.da_to_va       = xp70_rproc_da_to_va,
> +};
> +
> +/**
> + * Firmware handler operations: sanity, boot address, load ...
> + */
> +
> +static struct resource_table empty_rsc_tbl = {
> +	.ver = 1,
> +	.num = 0,
> +};
> +
> +static struct resource_table *xp70_rproc_find_rsc_table(struct rproc *rproc,
> +					       const struct firmware *fw,
> +					       int *tablesz)
> +{
> +	if (!fw)
> +		return NULL;
> +
> +	*tablesz = sizeof(empty_rsc_tbl);
> +	return &empty_rsc_tbl;
> +}
> +
> +static struct resource_table *xp70_rproc_find_loaded_rsc_table(struct rproc *rproc,
> +						      const struct firmware *fw)
> +{
> +	if (!fw)
> +		return NULL;
> +
> +	return &empty_rsc_tbl;
> +}
> +
> +static struct rproc_fw_ops xp70_rproc_fw_ops = {
> +	.find_rsc_table = xp70_rproc_find_rsc_table,
> +	.find_loaded_rsc_table = xp70_rproc_find_loaded_rsc_table,
> +};
> +
> +/**
> +  * xp70_rproc_alloc - allocate and initialise xp70 rproc
> +  * @pdev: Pointer to the platform_device struct
> +  * @fw_name: Name of firmware for rproc to use
> +  *
> +  * Function for allocating and initialising a xp70 rproc for use by
> +  * device drivers whose IP is based around the xp70 slim core. It
> +  * obtains and enables any clocks required by the xp70 core and also
> +  * ioremaps the various IO.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct st_xp70_rproc *xp70_rproc;
> +	struct device_node *np = dev->of_node;
> +	struct rproc *rproc;
> +	struct resource *res;
> +	int err, i;
> +	const struct rproc_fw_ops *elf_ops;
> +
> +	if (!np || !fw_name)
> +		return ERR_PTR(-EINVAL);
> +
> +	if (!of_device_is_compatible(np, "st,xp70-rproc"))
> +		return ERR_PTR(-EINVAL);
> +
> +	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
> +			fw_name, sizeof(*xp70_rproc));
> +	if (!rproc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	rproc->has_iommu = false;
> +
> +	xp70_rproc = rproc->priv;
> +	xp70_rproc->rproc = rproc;
> +
> +	/* Get standard ELF ops */
> +	elf_ops = rproc_get_elf_ops();
> +
> +	/* Use some generic elf ops */
> +	xp70_rproc_fw_ops.load = elf_ops->load;
> +	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
> +
> +	rproc->fw_ops = &xp70_rproc_fw_ops;
> +
> +	/* get imem and dmem */
> +	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
> +		res = xp70_rproc->mem[i].io_res;
> +
> +		res = platform_get_resource_byname
> +			(pdev, IORESOURCE_MEM, mem_names[i]);
> +
> +		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
> +		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
> +			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
> +			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
> +			goto err;
> +		}
> +		xp70_rproc->mem[i].bus_addr = res->start;
> +		xp70_rproc->mem[i].size = resource_size(res);
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
> +
> +	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->slimcore)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
> +		err = PTR_ERR(xp70_rproc->slimcore);
> +		goto err;
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
> +
> +	xp70_rproc->peri = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->peri)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
> +		err = PTR_ERR(xp70_rproc->peri);
> +		goto err;
> +	}
> +
> +	err = xp70_clk_get(xp70_rproc, dev);
> +	if (err)
> +		goto err;
> +
> +	/* Register as a remoteproc device */
> +	err = rproc_add(rproc);
> +	if (err) {
> +		dev_err(dev, "registration of xp70 remoteproc failed\n");
> +		goto err;
> +	}
> +
> +	dev_dbg(dev, "XP70 rproc init successful\n");
> +	return rproc;
> +
> +err:
> +	rproc_put(rproc);
> +	return ERR_PTR(err);
> +}
> +EXPORT_SYMBOL(xp70_rproc_alloc);
> +
> +/**
> +  * xp70_rproc_put - put xp70 rproc resources
> +  * @xp70_rproc: Pointer to the st_xp70_rproc struct
> +  *
> +  * Function for calling respective _put() functions on
> +  * xp70_rproc resources.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk;
> +
> +	if (!xp70_rproc)
> +		return;
> +
> +	rproc_put(xp70_rproc->rproc);
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> +		clk_put(xp70_rproc->clks[clk]);
> +
> +}
> +EXPORT_SYMBOL(xp70_rproc_put);
> +
> +MODULE_AUTHOR("Peter Griffin");
> +MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
> new file mode 100644
> index 0000000..3aba2de
> --- /dev/null
> +++ b/include/linux/remoteproc/st_xp70_rproc.h
> @@ -0,0 +1,56 @@
> +/*
> + * st_xp70_rproc.h
> + *
> + * Copyright (C) 2016 STMicroelectronics
> + * Author: Peter Griffin <peter.griffin@linaro.org>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +#ifndef _ST_XP70_H
> +#define _ST_XP70_H
> +
> +#define XP70_MEM_MAX 2
> +#define XP70_MAX_CLK 4
> +#define NAME_SZ 10
> +
> +enum {
> +	DMEM,
> +	IMEM,
> +};
> +
> +/**
> + * struct xp70_mem - xp70 internal memory structure
> + * @cpu_addr: MPU virtual address of the memory region
> + * @bus_addr: Bus address used to access the memory region
> + * @dev_addr: Device address from Wakeup M3 view
> + * @size: Size of the memory region
> + */
> +struct xp70_mem {
> +	void __iomem *cpu_addr;
> +	phys_addr_t bus_addr;
> +	u32 dev_addr;
> +	size_t size;
> +	struct resource *io_res;
> +};
> +
> +/**
> + * struct st_xp70_rproc - XP70 slim core
> + * @rproc: rproc handle
> + * @pdev: pointer to platform device
> + * @mem: xp70 memory information
> + * @slimcore: xp70 slimcore regs
> + * @peri: xp70 peripheral regs
> + * @clks: xp70 clocks
> + */
> +struct st_xp70_rproc {
> +	struct rproc *rproc;
> +	struct platform_device *pdev;
> +	struct xp70_mem mem[XP70_MEM_MAX];
> +	void __iomem *slimcore;
> +	void __iomem *peri;
> +	struct clk *clks[XP70_MAX_CLK];
> +};
> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> +
> +#endif

Hi Peter

Applying this series on top of v4.6 kernel leads to the following 
compilation error due to patch 01/18 :

drivers/remoteproc/st_xp70_rproc.c: In function 'xp70_rproc_alloc':
drivers/remoteproc/st_xp70_rproc.c:291:2: error: implicit declaration of 
function 'rproc_get_elf_ops' [-Werror=implicit-function-declaration]
   elf_ops = rproc_get_elf_ops();
   ^
   LD [M]  drivers/remoteproc/remoteproc.o


Patrice

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

* [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-05-27 13:15     ` Patrice Chotard
  0 siblings, 0 replies; 113+ messages in thread
From: Patrice Chotard @ 2016-05-27 13:15 UTC (permalink / raw)
  To: linux-arm-kernel



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> XP70 slim core is used as a basis for many IPs in the STi
> chipsets such as fdma, display, and demux. To avoid
> duplicating the elf loading code in each device driver
> an xp70 rproc driver has been created.
>
> This driver is designed to be used by other device drivers
> such as fdma, or demux whose IP is based around a xp70 slimcore.
> The device driver can call xp70_rproc_alloc() to allocate
> an xp70 rproc and xp70_rproc_put() when finished.
>
> This driver takes care of ioremapping the xp70
> registers (dmem, imem, slimcore, peripherals), whose offsets
> and sizes can change between IP's. It also obtains and enables
> any clocks used by the device. This approach avoids having
> a double mapping of the registers as xp70_rproc does not register
> its own platform device. It also maps well to device tree
> abstraction as it allows us to have one dt node for the whole
> device.
>
> All of the generic rproc elf loading code can be reused, and
> we provide start() stop() hooks to start and stop the xp70
> core once the firmware has been loaded. This has been tested
> successfully with fdma driver.
>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>   drivers/remoteproc/Kconfig               |   8 +
>   drivers/remoteproc/Makefile              |   1 +
>   drivers/remoteproc/st_xp70_rproc.c       | 380 +++++++++++++++++++++++++++++++
>   include/linux/remoteproc/st_xp70_rproc.h |  56 +++++
>   4 files changed, 445 insertions(+)
>   create mode 100644 drivers/remoteproc/st_xp70_rproc.c
>   create mode 100644 include/linux/remoteproc/st_xp70_rproc.h
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 72e97d7..9e48fd1 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -86,4 +86,12 @@ config ST_REMOTEPROC
>   	  processor framework.
>   	  This can be either built-in or a loadable module.
>   
> +config ST_XP70_REMOTEPROC
> +	tristate "XP70 slim remoteproc support"
> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support xp70 slim core.
> +	  If unsure say N.
> +
>   endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 279cb2e..b5dab8e 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -12,3 +12,4 @@ obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
>   obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
>   obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
>   obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
> +obj-$(CONFIG_ST_XP70_REMOTEPROC)	+= st_xp70_rproc.o
> diff --git a/drivers/remoteproc/st_xp70_rproc.c b/drivers/remoteproc/st_xp70_rproc.c
> new file mode 100644
> index 0000000..6a78e7c
> --- /dev/null
> +++ b/drivers/remoteproc/st_xp70_rproc.c
> @@ -0,0 +1,380 @@
> +/*
> + * st_xp70_rproc.c
> + *
> + * Copyright (C) 2016 STMicroelectronics
> + * Author: Peter Griffin <peter.griffin@st.com>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/elf.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/remoteproc.h>
> +#include <linux/remoteproc/st_xp70_rproc.h>
> +#include "remoteproc_internal.h"
> +
> +/* slimcore registers */
> +#define XP70_ID_OFST		0x0
> +#define XP70_VER_OFST		0x4
> +
> +#define XP70_EN_OFST		0x8
> +#define XP70_EN_RUN			BIT(0)
> +
> +#define XP70_CLK_GATE_OFST	0xC
> +#define XP70_CLK_GATE_DIS		BIT(0)
> +#define XP70_CLK_GATE_RESET		BIT(2)
> +
> +#define XP70_SLIM_PC_OFST	0x20
> +
> +/* dmem registers */
> +#define XP70_REV_ID_OFST	0x0
> +#define XP70_REV_ID_MIN_MASK		GENMASK(15, 8)
> +#define XP70_REV_ID_MIN(id)		((id & XP70_REV_ID_MIN_MASK) >> 8)
> +#define XP70_REV_ID_MAJ_MASK		GENMASK(23, 16)
> +#define XP70_REV_ID_MAJ(id)		((id & XP70_REV_ID_MAJ_MASK) >> 16)
> +
> +
> +/* peripherals registers */
> +#define XP70_STBUS_SYNC_OFST	0xF88
> +#define XP70_STBUS_SYNC_DIS		BIT(0)
> +
> +#define XP70_INT_SET_OFST	0xFD4
> +#define XP70_INT_CLR_OFST	0xFD8
> +#define XP70_INT_MASK_OFST	0xFDC
> +
> +#define XP70_CMD_CLR_OFST	0xFC8
> +#define XP70_CMD_MASK_OFST	0xFCC
> +
> +const char *mem_names[XP70_MEM_MAX] = {
> +	[DMEM]		= "dmem",
> +	[IMEM]		= "imem",
> +};
> +
> +static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
> +{
> +	int clk, err = 0;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
> +		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
> +		if (IS_ERR(xp70_rproc->clks[clk])) {
> +			err = PTR_ERR(xp70_rproc->clks[clk]);
> +			if (err == -EPROBE_DEFER)
> +				goto err_put_clks;
> +			xp70_rproc->clks[clk] = NULL;
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_put_clks:
> +	while (--clk >= 0)
> +		clk_put(xp70_rproc->clks[clk]);
> +
> +	return err;
> +}
> +
> +static void xp70_clk_disable(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> +		clk_disable_unprepare(xp70_rproc->clks[clk]);
> +}
> +
> +static int xp70_clk_enable(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk, ret;
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++) {
> +		ret = clk_prepare_enable(xp70_rproc->clks[clk]);
> +		if (ret)
> +			goto err_disable_clks;
> +	}
> +
> +	return 0;
> +
> +err_disable_clks:
> +	while (--clk >= 0)
> +		clk_disable_unprepare(xp70_rproc->clks[clk]);
> +
> +	return ret;
> +}
> +
> +/**
> + * Remoteproc xp70 specific device handlers
> + */
> +static int xp70_rproc_start(struct rproc *rproc)
> +{
> +	struct device *dev = &rproc->dev;
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	unsigned long hw_id, hw_ver, fw_rev;
> +	u32 val, ret = 0;
> +
> +	ret = xp70_clk_enable(xp70_rproc);
> +	if (ret) {
> +		dev_err(dev, "Failed to enable clocks\n");
> +		goto err_clk;
> +	}
> +
> +	/* disable CPU pipeline clock & reset cpu pipeline */
> +	val = XP70_CLK_GATE_DIS | XP70_CLK_GATE_RESET;
> +	writel_relaxed(val, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	/* disable SLIM core STBus sync */
> +	writel_relaxed(XP70_STBUS_SYNC_DIS,
> +		xp70_rproc->peri + XP70_STBUS_SYNC_OFST);
> +
> +	/* enable cpu pipeline clock */
> +	writel_relaxed(!XP70_CLK_GATE_DIS,
> +		xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	/* clear int & cmd mailbox */
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_CLR_OFST);
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_CLR_OFST);
> +
> +	/* enable all channels cmd & int */
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> +	writel_relaxed(~0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> +
> +	/* enable cpu */
> +	writel(XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
> +
> +	hw_id = readl_relaxed(xp70_rproc->slimcore + XP70_ID_OFST);
> +	hw_ver = readl_relaxed(xp70_rproc->slimcore + XP70_VER_OFST);
> +
> +	fw_rev = readl_relaxed(xp70_rproc->mem[DMEM].cpu_addr +
> +			XP70_REV_ID_OFST);
> +
> +	dev_info(dev, "fw rev:%ld.%ld on SLIM %ld.%ld\n",
> +		 XP70_REV_ID_MAJ(fw_rev), XP70_REV_ID_MIN(fw_rev),
> +		 hw_id, hw_ver);
> +
> +	dev_dbg(dev, "XP70 started\n");
> +
> +err_clk:
> +	return ret;
> +}
> +
> +static int xp70_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	u32 val;
> +
> +	/* mask all (cmd & int) channels */
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> +	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> +
> +	/* disable cpu pipeline clock */
> +	writel_relaxed(XP70_CLK_GATE_DIS
> +		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> +
> +	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
> +
> +	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
> +	if (val & XP70_EN_RUN)
> +		dev_warn(&rproc->dev, "Failed to disable XP70");
> +
> +	xp70_clk_disable(xp70_rproc);
> +
> +	dev_dbg(&rproc->dev, "xp70 stopped\n");
> +
> +	return 0;
> +}
> +
> +static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
> +{
> +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> +	void *va = NULL;
> +	int i;
> +
> +	for (i = 0; i < XP70_MEM_MAX; i++) {
> +
> +		if (da != xp70_rproc->mem[i].bus_addr)
> +			continue;
> +
> +		va = xp70_rproc->mem[i].cpu_addr;
> +			break;
> +	}
> +
> +	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
> +		, __func__, da, len, va);
> +
> +	return va;
> +}
> +
> +static struct rproc_ops xp70_rproc_ops = {
> +	.start		= xp70_rproc_start,
> +	.stop		= xp70_rproc_stop,
> +	.da_to_va       = xp70_rproc_da_to_va,
> +};
> +
> +/**
> + * Firmware handler operations: sanity, boot address, load ...
> + */
> +
> +static struct resource_table empty_rsc_tbl = {
> +	.ver = 1,
> +	.num = 0,
> +};
> +
> +static struct resource_table *xp70_rproc_find_rsc_table(struct rproc *rproc,
> +					       const struct firmware *fw,
> +					       int *tablesz)
> +{
> +	if (!fw)
> +		return NULL;
> +
> +	*tablesz = sizeof(empty_rsc_tbl);
> +	return &empty_rsc_tbl;
> +}
> +
> +static struct resource_table *xp70_rproc_find_loaded_rsc_table(struct rproc *rproc,
> +						      const struct firmware *fw)
> +{
> +	if (!fw)
> +		return NULL;
> +
> +	return &empty_rsc_tbl;
> +}
> +
> +static struct rproc_fw_ops xp70_rproc_fw_ops = {
> +	.find_rsc_table = xp70_rproc_find_rsc_table,
> +	.find_loaded_rsc_table = xp70_rproc_find_loaded_rsc_table,
> +};
> +
> +/**
> +  * xp70_rproc_alloc - allocate and initialise xp70 rproc
> +  * @pdev: Pointer to the platform_device struct
> +  * @fw_name: Name of firmware for rproc to use
> +  *
> +  * Function for allocating and initialising a xp70 rproc for use by
> +  * device drivers whose IP is based around the xp70 slim core. It
> +  * obtains and enables any clocks required by the xp70 core and also
> +  * ioremaps the various IO.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct st_xp70_rproc *xp70_rproc;
> +	struct device_node *np = dev->of_node;
> +	struct rproc *rproc;
> +	struct resource *res;
> +	int err, i;
> +	const struct rproc_fw_ops *elf_ops;
> +
> +	if (!np || !fw_name)
> +		return ERR_PTR(-EINVAL);
> +
> +	if (!of_device_is_compatible(np, "st,xp70-rproc"))
> +		return ERR_PTR(-EINVAL);
> +
> +	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
> +			fw_name, sizeof(*xp70_rproc));
> +	if (!rproc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	rproc->has_iommu = false;
> +
> +	xp70_rproc = rproc->priv;
> +	xp70_rproc->rproc = rproc;
> +
> +	/* Get standard ELF ops */
> +	elf_ops = rproc_get_elf_ops();
> +
> +	/* Use some generic elf ops */
> +	xp70_rproc_fw_ops.load = elf_ops->load;
> +	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
> +
> +	rproc->fw_ops = &xp70_rproc_fw_ops;
> +
> +	/* get imem and dmem */
> +	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
> +		res = xp70_rproc->mem[i].io_res;
> +
> +		res = platform_get_resource_byname
> +			(pdev, IORESOURCE_MEM, mem_names[i]);
> +
> +		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
> +		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
> +			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
> +			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
> +			goto err;
> +		}
> +		xp70_rproc->mem[i].bus_addr = res->start;
> +		xp70_rproc->mem[i].size = resource_size(res);
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
> +
> +	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->slimcore)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
> +		err = PTR_ERR(xp70_rproc->slimcore);
> +		goto err;
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
> +
> +	xp70_rproc->peri = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(xp70_rproc->peri)) {
> +		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
> +		err = PTR_ERR(xp70_rproc->peri);
> +		goto err;
> +	}
> +
> +	err = xp70_clk_get(xp70_rproc, dev);
> +	if (err)
> +		goto err;
> +
> +	/* Register as a remoteproc device */
> +	err = rproc_add(rproc);
> +	if (err) {
> +		dev_err(dev, "registration of xp70 remoteproc failed\n");
> +		goto err;
> +	}
> +
> +	dev_dbg(dev, "XP70 rproc init successful\n");
> +	return rproc;
> +
> +err:
> +	rproc_put(rproc);
> +	return ERR_PTR(err);
> +}
> +EXPORT_SYMBOL(xp70_rproc_alloc);
> +
> +/**
> +  * xp70_rproc_put - put xp70 rproc resources
> +  * @xp70_rproc: Pointer to the st_xp70_rproc struct
> +  *
> +  * Function for calling respective _put() functions on
> +  * xp70_rproc resources.
> +  *
> +  * Returns rproc pointer or PTR_ERR() on error.
> +  */
> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
> +{
> +	int clk;
> +
> +	if (!xp70_rproc)
> +		return;
> +
> +	rproc_put(xp70_rproc->rproc);
> +
> +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> +		clk_put(xp70_rproc->clks[clk]);
> +
> +}
> +EXPORT_SYMBOL(xp70_rproc_put);
> +
> +MODULE_AUTHOR("Peter Griffin");
> +MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
> new file mode 100644
> index 0000000..3aba2de
> --- /dev/null
> +++ b/include/linux/remoteproc/st_xp70_rproc.h
> @@ -0,0 +1,56 @@
> +/*
> + * st_xp70_rproc.h
> + *
> + * Copyright (C) 2016 STMicroelectronics
> + * Author: Peter Griffin <peter.griffin@linaro.org>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +#ifndef _ST_XP70_H
> +#define _ST_XP70_H
> +
> +#define XP70_MEM_MAX 2
> +#define XP70_MAX_CLK 4
> +#define NAME_SZ 10
> +
> +enum {
> +	DMEM,
> +	IMEM,
> +};
> +
> +/**
> + * struct xp70_mem - xp70 internal memory structure
> + * @cpu_addr: MPU virtual address of the memory region
> + * @bus_addr: Bus address used to access the memory region
> + * @dev_addr: Device address from Wakeup M3 view
> + * @size: Size of the memory region
> + */
> +struct xp70_mem {
> +	void __iomem *cpu_addr;
> +	phys_addr_t bus_addr;
> +	u32 dev_addr;
> +	size_t size;
> +	struct resource *io_res;
> +};
> +
> +/**
> + * struct st_xp70_rproc - XP70 slim core
> + * @rproc: rproc handle
> + * @pdev: pointer to platform device
> + * @mem: xp70 memory information
> + * @slimcore: xp70 slimcore regs
> + * @peri: xp70 peripheral regs
> + * @clks: xp70 clocks
> + */
> +struct st_xp70_rproc {
> +	struct rproc *rproc;
> +	struct platform_device *pdev;
> +	struct xp70_mem mem[XP70_MEM_MAX];
> +	void __iomem *slimcore;
> +	void __iomem *peri;
> +	struct clk *clks[XP70_MAX_CLK];
> +};
> +
> +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
> +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> +
> +#endif

Hi Peter

Applying this series on top of v4.6 kernel leads to the following 
compilation error due to patch 01/18 :

drivers/remoteproc/st_xp70_rproc.c: In function 'xp70_rproc_alloc':
drivers/remoteproc/st_xp70_rproc.c:291:2: error: implicit declaration of 
function 'rproc_get_elf_ops' [-Werror=implicit-function-declaration]
   elf_ops = rproc_get_elf_ops();
   ^
   LD [M]  drivers/remoteproc/remoteproc.o


Patrice

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

* Re: [PATCH v4 04/18] dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding documentation
@ 2016-05-27 15:44     ` Rob Herring
  0 siblings, 0 replies; 113+ messages in thread
From: Rob Herring @ 2016-05-27 15:44 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, devicetree, linux-remoteproc, dmaengine,
	lee.jones, Ludovic Barre

On Wed, May 25, 2016 at 05:06:38PM +0100, Peter Griffin wrote:
> This patch adds the DT binding documentation for the FDMA constroller
> found on STi based chipsets from STMicroelectronics.
> 
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  Documentation/devicetree/bindings/dma/st_fdma.txt | 87 +++++++++++++++++++++++
>  1 file changed, 87 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v4 04/18] dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding documentation
@ 2016-05-27 15:44     ` Rob Herring
  0 siblings, 0 replies; 113+ messages in thread
From: Rob Herring @ 2016-05-27 15:44 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, Ludovic Barre

On Wed, May 25, 2016 at 05:06:38PM +0100, Peter Griffin wrote:
> This patch adds the DT binding documentation for the FDMA constroller
> found on STi based chipsets from STMicroelectronics.
> 
> Signed-off-by: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
> Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/dma/st_fdma.txt | 87 +++++++++++++++++++++++
>  1 file changed, 87 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 04/18] dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding documentation
@ 2016-05-27 15:44     ` Rob Herring
  0 siblings, 0 replies; 113+ messages in thread
From: Rob Herring @ 2016-05-27 15:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 25, 2016 at 05:06:38PM +0100, Peter Griffin wrote:
> This patch adds the DT binding documentation for the FDMA constroller
> found on STi based chipsets from STMicroelectronics.
> 
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  Documentation/devicetree/bindings/dma/st_fdma.txt | 87 +++++++++++++++++++++++
>  1 file changed, 87 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
@ 2016-05-27 15:47     ` Rob Herring
  0 siblings, 0 replies; 113+ messages in thread
From: Rob Herring @ 2016-05-27 15:47 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, lee.jones, devicetree, dmaengine,
	linux-remoteproc, arnaud.pouliquen, broonie

On Wed, May 25, 2016 at 05:06:44PM +0100, Peter Griffin wrote:
> uniperiph-id, version and mode are ST specific bindings and
> need the 'st,' prefix. Update the examples, as otherwise copying
> them yields a runtime error parsing the DT node.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> Cc: arnaud.pouliquen@st.com
> Cc: broonie@kernel.org
> ---
>  .../devicetree/bindings/sound/st,sti-asoc-card.txt   | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
@ 2016-05-27 15:47     ` Rob Herring
  0 siblings, 0 replies; 113+ messages in thread
From: Rob Herring @ 2016-05-27 15:47 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA,
	arnaud.pouliquen-qxv4g6HH51o, broonie-DgEjT+Ai2ygdnm+yROfE0A

On Wed, May 25, 2016 at 05:06:44PM +0100, Peter Griffin wrote:
> uniperiph-id, version and mode are ST specific bindings and
> need the 'st,' prefix. Update the examples, as otherwise copying
> them yields a runtime error parsing the DT node.
> 
> Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: arnaud.pouliquen-qxv4g6HH51o@public.gmane.org
> Cc: broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
> ---
>  .../devicetree/bindings/sound/st,sti-asoc-card.txt   | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
@ 2016-05-27 15:47     ` Rob Herring
  0 siblings, 0 replies; 113+ messages in thread
From: Rob Herring @ 2016-05-27 15:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 25, 2016 at 05:06:44PM +0100, Peter Griffin wrote:
> uniperiph-id, version and mode are ST specific bindings and
> need the 'st,' prefix. Update the examples, as otherwise copying
> them yields a runtime error parsing the DT node.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> Cc: arnaud.pouliquen at st.com
> Cc: broonie at kernel.org
> ---
>  .../devicetree/bindings/sound/st,sti-asoc-card.txt   | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-05-27 16:13       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-27 16:13 UTC (permalink / raw)
  To: Patrice Chotard
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, vinod.koul, ohad, bjorn.andersson, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc

Hi Patrice,

On Fri, 27 May 2016, Patrice Chotard wrote:
<snip>

> >+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
> >+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> >+
> >+#endif
> 
> Hi Peter
> 
> Applying this series on top of v4.6 kernel leads to the following
> compilation error due to patch 01/18 :
> 
> drivers/remoteproc/st_xp70_rproc.c: In function 'xp70_rproc_alloc':
> drivers/remoteproc/st_xp70_rproc.c:291:2: error: implicit
> declaration of function 'rproc_get_elf_ops'
> [-Werror=implicit-function-declaration]
>   elf_ops = rproc_get_elf_ops();
>   ^
>   LD [M]  drivers/remoteproc/remoteproc.o

Whoops. Looks like I forgot to include the first patch of the series. Doh! I will
include it when I send v5.

The missing patch looks like this. Bjorn do you have any issues with adding this
interface?

regards,

Peter.



>From 4664bb628cb5c99a43976a0b74ae1ee6cb05a68e Mon Sep 17 00:00:00 2001
From: Peter Griffin <peter.griffin@linaro.org>
Date: Wed, 25 May 2016 09:54:02 +0100
Subject: [PATCH 01/19] remoteproc: add a rproc_get_elf_ops interface

This allows us to re-use some of the generic fw_ops such
as rproc_elf_sanity_check() and rproc_elf_load_segments() whilst
overriding some of the others with our own implementation.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/remoteproc/remoteproc_elf_loader.c | 6 ++++++
 include/linux/remoteproc.h                 | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index ce283a5..a3e06df 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -335,3 +335,9 @@ const struct rproc_fw_ops rproc_elf_fw_ops = {
 	.sanity_check = rproc_elf_sanity_check,
 	.get_boot_addr = rproc_elf_get_boot_addr
 };
+
+const struct rproc_fw_ops *rproc_get_elf_ops(void)
+{
+	return &rproc_elf_fw_ops;
+}
+EXPORT_SYMBOL_GPL(rproc_get_elf_ops);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 9c4e138..b0b06c8 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -495,6 +495,8 @@ int rproc_boot(struct rproc *rproc);
 void rproc_shutdown(struct rproc *rproc);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 
+const struct rproc_fw_ops *rproc_get_elf_ops(void);
+
 static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
 {
 	return container_of(vdev, struct rproc_vdev, vdev);
-- 
1.9.1

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

* Re: [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-05-27 16:13       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-27 16:13 UTC (permalink / raw)
  To: Patrice Chotard
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA

Hi Patrice,

On Fri, 27 May 2016, Patrice Chotard wrote:
<snip>

> >+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
> >+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> >+
> >+#endif
> 
> Hi Peter
> 
> Applying this series on top of v4.6 kernel leads to the following
> compilation error due to patch 01/18 :
> 
> drivers/remoteproc/st_xp70_rproc.c: In function 'xp70_rproc_alloc':
> drivers/remoteproc/st_xp70_rproc.c:291:2: error: implicit
> declaration of function 'rproc_get_elf_ops'
> [-Werror=implicit-function-declaration]
>   elf_ops = rproc_get_elf_ops();
>   ^
>   LD [M]  drivers/remoteproc/remoteproc.o

Whoops. Looks like I forgot to include the first patch of the series. Doh! I will
include it when I send v5.

The missing patch looks like this. Bjorn do you have any issues with adding this
interface?

regards,

Peter.



>From 4664bb628cb5c99a43976a0b74ae1ee6cb05a68e Mon Sep 17 00:00:00 2001
From: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Date: Wed, 25 May 2016 09:54:02 +0100
Subject: [PATCH 01/19] remoteproc: add a rproc_get_elf_ops interface

This allows us to re-use some of the generic fw_ops such
as rproc_elf_sanity_check() and rproc_elf_load_segments() whilst
overriding some of the others with our own implementation.

Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/remoteproc/remoteproc_elf_loader.c | 6 ++++++
 include/linux/remoteproc.h                 | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index ce283a5..a3e06df 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -335,3 +335,9 @@ const struct rproc_fw_ops rproc_elf_fw_ops = {
 	.sanity_check = rproc_elf_sanity_check,
 	.get_boot_addr = rproc_elf_get_boot_addr
 };
+
+const struct rproc_fw_ops *rproc_get_elf_ops(void)
+{
+	return &rproc_elf_fw_ops;
+}
+EXPORT_SYMBOL_GPL(rproc_get_elf_ops);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 9c4e138..b0b06c8 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -495,6 +495,8 @@ int rproc_boot(struct rproc *rproc);
 void rproc_shutdown(struct rproc *rproc);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 
+const struct rproc_fw_ops *rproc_get_elf_ops(void);
+
 static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
 {
 	return container_of(vdev, struct rproc_vdev, vdev);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-05-27 16:13       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-05-27 16:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Patrice,

On Fri, 27 May 2016, Patrice Chotard wrote:
<snip>

> >+struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
> >+void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> >+
> >+#endif
> 
> Hi Peter
> 
> Applying this series on top of v4.6 kernel leads to the following
> compilation error due to patch 01/18 :
> 
> drivers/remoteproc/st_xp70_rproc.c: In function 'xp70_rproc_alloc':
> drivers/remoteproc/st_xp70_rproc.c:291:2: error: implicit
> declaration of function 'rproc_get_elf_ops'
> [-Werror=implicit-function-declaration]
>   elf_ops = rproc_get_elf_ops();
>   ^
>   LD [M]  drivers/remoteproc/remoteproc.o

Whoops. Looks like I forgot to include the first patch of the series. Doh! I will
include it when I send v5.

The missing patch looks like this. Bjorn do you have any issues with adding this
interface?

regards,

Peter.



>From 4664bb628cb5c99a43976a0b74ae1ee6cb05a68e Mon Sep 17 00:00:00 2001
From: Peter Griffin <peter.griffin@linaro.org>
Date: Wed, 25 May 2016 09:54:02 +0100
Subject: [PATCH 01/19] remoteproc: add a rproc_get_elf_ops interface

This allows us to re-use some of the generic fw_ops such
as rproc_elf_sanity_check() and rproc_elf_load_segments() whilst
overriding some of the others with our own implementation.

Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
 drivers/remoteproc/remoteproc_elf_loader.c | 6 ++++++
 include/linux/remoteproc.h                 | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index ce283a5..a3e06df 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -335,3 +335,9 @@ const struct rproc_fw_ops rproc_elf_fw_ops = {
 	.sanity_check = rproc_elf_sanity_check,
 	.get_boot_addr = rproc_elf_get_boot_addr
 };
+
+const struct rproc_fw_ops *rproc_get_elf_ops(void)
+{
+	return &rproc_elf_fw_ops;
+}
+EXPORT_SYMBOL_GPL(rproc_get_elf_ops);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 9c4e138..b0b06c8 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -495,6 +495,8 @@ int rproc_boot(struct rproc *rproc);
 void rproc_shutdown(struct rproc *rproc);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 
+const struct rproc_fw_ops *rproc_get_elf_ops(void);
+
 static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
 {
 	return container_of(vdev, struct rproc_vdev, vdev);
-- 
1.9.1

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

* Re: [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
  2016-05-25 16:06   ` Peter Griffin
@ 2016-05-27 17:14     ` Mark Brown
  -1 siblings, 0 replies; 113+ messages in thread
From: Mark Brown @ 2016-05-27 17:14 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, lee.jones, devicetree, dmaengine,
	linux-remoteproc, arnaud.pouliquen

[-- Attachment #1: Type: text/plain, Size: 795 bytes --]

On Wed, May 25, 2016 at 05:06:44PM +0100, Peter Griffin wrote:
> uniperiph-id, version and mode are ST specific bindings and
> need the 'st,' prefix. Update the examples, as otherwise copying
> them yields a runtime error parsing the DT node.

You've not copied me on the rest of the series so I've no idea what's
going on with dependencies.  When sending a patch series it is important
to ensure that all the various maintainers understand what the
relationship between the patches as the expecation is that there will be
interdependencies.  Either copy everyone on the whole series or at least
copy them on the cover letter and explain what's going on.  If there are
no strong interdependencies then it's generally simplest to just send
the patches separately to avoid any possible confusion.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
@ 2016-05-27 17:14     ` Mark Brown
  0 siblings, 0 replies; 113+ messages in thread
From: Mark Brown @ 2016-05-27 17:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 25, 2016 at 05:06:44PM +0100, Peter Griffin wrote:
> uniperiph-id, version and mode are ST specific bindings and
> need the 'st,' prefix. Update the examples, as otherwise copying
> them yields a runtime error parsing the DT node.

You've not copied me on the rest of the series so I've no idea what's
going on with dependencies.  When sending a patch series it is important
to ensure that all the various maintainers understand what the
relationship between the patches as the expecation is that there will be
interdependencies.  Either copy everyone on the whole series or at least
copy them on the cover letter and explain what's going on.  If there are
no strong interdependencies then it's generally simplest to just send
the patches separately to avoid any possible confusion.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160527/17a8742a/attachment.sig>

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

* Re: [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
  2016-05-25 16:06   ` Peter Griffin
  (?)
@ 2016-05-31  8:55     ` Arnaud Pouliquen
  -1 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  8:55 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc, broonie

Hi Peter,

On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch enables the STi ALSA drivers found on STi platforms
> as well as the simple-card driver which is a dependency to have
> working sound.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> Cc: arnaud.pouliquen@st.com
> Cc: broonie@kernel.org
> ---
>  arch/arm/configs/multi_v7_defconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 5eee45b..0ced665 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -589,6 +589,9 @@ CONFIG_SND_SOC_AK4642=m
>  CONFIG_SND_SOC_SGTL5000=m
>  CONFIG_SND_SOC_SPDIF=m
>  CONFIG_SND_SOC_WM8978=m
> +CONFIG_SND_SOC_STI=m
> +CONFIG_SND_SOC_STI_SAS=m
> +CONFIG_SND_SIMPLE_CARD=m
Simple card config seems enabled by default, at least on 4.7 rc1.

Regards,
Arnaud
>  CONFIG_USB=y
>  CONFIG_USB_XHCI_HCD=y
>  CONFIG_USB_XHCI_MVEBU=y
> 

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

* Re: [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
@ 2016-05-31  8:55     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  8:55 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc, broonie

Hi Peter,

On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch enables the STi ALSA drivers found on STi platforms
> as well as the simple-card driver which is a dependency to have
> working sound.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> Cc: arnaud.pouliquen@st.com
> Cc: broonie@kernel.org
> ---
>  arch/arm/configs/multi_v7_defconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 5eee45b..0ced665 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -589,6 +589,9 @@ CONFIG_SND_SOC_AK4642=m
>  CONFIG_SND_SOC_SGTL5000=m
>  CONFIG_SND_SOC_SPDIF=m
>  CONFIG_SND_SOC_WM8978=m
> +CONFIG_SND_SOC_STI=m
> +CONFIG_SND_SOC_STI_SAS=m
> +CONFIG_SND_SIMPLE_CARD=m
Simple card config seems enabled by default, at least on 4.7 rc1.

Regards,
Arnaud
>  CONFIG_USB=y
>  CONFIG_USB_XHCI_HCD=y
>  CONFIG_USB_XHCI_MVEBU=y
> 

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

* [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
@ 2016-05-31  8:55     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Peter,

On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch enables the STi ALSA drivers found on STi platforms
> as well as the simple-card driver which is a dependency to have
> working sound.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> Cc: arnaud.pouliquen at st.com
> Cc: broonie at kernel.org
> ---
>  arch/arm/configs/multi_v7_defconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 5eee45b..0ced665 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -589,6 +589,9 @@ CONFIG_SND_SOC_AK4642=m
>  CONFIG_SND_SOC_SGTL5000=m
>  CONFIG_SND_SOC_SPDIF=m
>  CONFIG_SND_SOC_WM8978=m
> +CONFIG_SND_SOC_STI=m
> +CONFIG_SND_SOC_STI_SAS=m
> +CONFIG_SND_SIMPLE_CARD=m
Simple card config seems enabled by default, at least on 4.7 rc1.

Regards,
Arnaud
>  CONFIG_USB=y
>  CONFIG_USB_XHCI_HCD=y
>  CONFIG_USB_XHCI_MVEBU=y
> 

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

* Re: [PATCH v4 15/18] ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
  2016-05-25 16:06   ` Peter Griffin
  (?)
@ 2016-05-31  9:05     ` Arnaud Pouliquen
  -1 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:05 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the dt node for the internal audio
> codec IP.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index b423836..60f95b6 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -746,5 +746,14 @@
>  				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
>  				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
>  		};
> +
> +		sti_sasg_codec: sti-sasg-codec {
> +			compatible = "st,stih407-sas-codec";
> +			#sound-dai-cells = <1>;
> +			status = "okay";
Should be set to disable in family and enabled it depending on boards
(stihxxx-b2120.dtsi)
> +			st,syscfg = <&syscfg_core>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_spdif_out >;
Declare pinctrl use in stihxxx-b2120.dtsi, should be set only if SPDIF used.

Regards
Arnaud
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 15/18] ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
@ 2016-05-31  9:05     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:05 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the dt node for the internal audio
> codec IP.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index b423836..60f95b6 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -746,5 +746,14 @@
>  				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
>  				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
>  		};
> +
> +		sti_sasg_codec: sti-sasg-codec {
> +			compatible = "st,stih407-sas-codec";
> +			#sound-dai-cells = <1>;
> +			status = "okay";
Should be set to disable in family and enabled it depending on boards
(stihxxx-b2120.dtsi)
> +			st,syscfg = <&syscfg_core>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_spdif_out >;
Declare pinctrl use in stihxxx-b2120.dtsi, should be set only if SPDIF used.

Regards
Arnaud
> +		};
>  	};
>  };
> 

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

* [PATCH v4 15/18] ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
@ 2016-05-31  9:05     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:05 UTC (permalink / raw)
  To: linux-arm-kernel



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the dt node for the internal audio
> codec IP.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index b423836..60f95b6 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -746,5 +746,14 @@
>  				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
>  				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
>  		};
> +
> +		sti_sasg_codec: sti-sasg-codec {
> +			compatible = "st,stih407-sas-codec";
> +			#sound-dai-cells = <1>;
> +			status = "okay";
Should be set to disable in family and enabled it depending on boards
(stihxxx-b2120.dtsi)
> +			st,syscfg = <&syscfg_core>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_spdif_out >;
Declare pinctrl use in stihxxx-b2120.dtsi, should be set only if SPDIF used.

Regards
Arnaud
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
  2016-05-25 16:06   ` Peter Griffin
  (?)
  (?)
@ 2016-05-31  9:14     ` Arnaud Pouliquen
  -1 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:14 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the DT nodes for the uniperif player
> IP blocks found on STiH407 family silicon.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 60f95b6..7ca149b 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -755,5 +755,81 @@
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&pinctrl_spdif_out >;
>  		};
> +
> +		sti_uni_player0: sti-uni-player@0 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
This does not work properly. You need to declare parent like this:
assigned-clocks = <&clk_s_d0_quadfs 0>, <&clk_s_d0_flexgen CLK_PCM_0>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 0>;

> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D80000 0x158>;
> +			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 2 0 1>;
> +			dai-name = "Uni Player #0 (HDMI)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <0>;
> +			st,version = <5>;
> +			st,mode = "HDMI";
> +		};
> +
> +		sti_uni_player1: sti-uni-player@1 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
assigned-clocks = <&clk_s_d0_quadfs 1>, <&clk_s_d0_flexgen CLK_PCM_1>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 1>;

> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D81000 0x158>;
> +			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 3 0 1>;
> +			dai-name = "Uni Player #1 (PIO)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <1>;
> +			st,version = <5>;
> +			st,mode = "PCM";
> +		};
> +
> +		sti_uni_player2: sti-uni-player@2 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
assigned-clocks = <&clk_s_d0_quadfs 2>, <&clk_s_d0_flexgen CLK_PCM_2>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 2>;
> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D82000 0x158>;
> +			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 4 0 1>;
> +			dai-name = "Uni Player #1 (DAC)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <2>;
> +			st,version = <5>;
> +			st,mode = "PCM";
> +		};
> +
> +		sti_uni_player3: sti-uni-player@3 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
> +			assigned-clock-rates = <50000000>;
assigned-clocks = <&clk_s_d0_quadfs 3>, <&clk_s_d0_flexgen CLK_SPDIFF>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 3>;

Regards,
Arnaud
> +			reg = <0x8D85000 0x158>;
> +			interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 7 0 1>;
> +			dma-names = "tx";
> +			dai-name = "Uni Player #1 (PIO)";
> +			st,uniperiph-id = <3>;
> +			st,version = <5>;
> +			st,mode = "SPDIF";
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
@ 2016-05-31  9:14     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:14 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the DT nodes for the uniperif player
> IP blocks found on STiH407 family silicon.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 60f95b6..7ca149b 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -755,5 +755,81 @@
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&pinctrl_spdif_out >;
>  		};
> +
> +		sti_uni_player0: sti-uni-player@0 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
This does not work properly. You need to declare parent like this:
assigned-clocks = <&clk_s_d0_quadfs 0>, <&clk_s_d0_flexgen CLK_PCM_0>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 0>;

> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D80000 0x158>;
> +			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 2 0 1>;
> +			dai-name = "Uni Player #0 (HDMI)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <0>;
> +			st,version = <5>;
> +			st,mode = "HDMI";
> +		};
> +
> +		sti_uni_player1: sti-uni-player@1 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
assigned-clocks = <&clk_s_d0_quadfs 1>, <&clk_s_d0_flexgen CLK_PCM_1>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 1>;

> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D81000 0x158>;
> +			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 3 0 1>;
> +			dai-name = "Uni Player #1 (PIO)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <1>;
> +			st,version = <5>;
> +			st,mode = "PCM";
> +		};
> +
> +		sti_uni_player2: sti-uni-player@2 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
assigned-clocks = <&clk_s_d0_quadfs 2>, <&clk_s_d0_flexgen CLK_PCM_2>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 2>;
> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D82000 0x158>;
> +			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 4 0 1>;
> +			dai-name = "Uni Player #1 (DAC)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <2>;
> +			st,version = <5>;
> +			st,mode = "PCM";
> +		};
> +
> +		sti_uni_player3: sti-uni-player@3 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
> +			assigned-clock-rates = <50000000>;
assigned-clocks = <&clk_s_d0_quadfs 3>, <&clk_s_d0_flexgen CLK_SPDIFF>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 3>;

Regards,
Arnaud
> +			reg = <0x8D85000 0x158>;
> +			interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 7 0 1>;
> +			dma-names = "tx";
> +			dai-name = "Uni Player #1 (PIO)";
> +			st,uniperiph-id = <3>;
> +			st,version = <5>;
> +			st,mode = "SPDIF";
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
@ 2016-05-31  9:14     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:14 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4
  Cc: lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the DT nodes for the uniperif player
> IP blocks found on STiH407 family silicon.
> 
> Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 60f95b6..7ca149b 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -755,5 +755,81 @@
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&pinctrl_spdif_out >;
>  		};
> +
> +		sti_uni_player0: sti-uni-player@0 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
This does not work properly. You need to declare parent like this:
assigned-clocks = <&clk_s_d0_quadfs 0>, <&clk_s_d0_flexgen CLK_PCM_0>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 0>;

> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D80000 0x158>;
> +			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 2 0 1>;
> +			dai-name = "Uni Player #0 (HDMI)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <0>;
> +			st,version = <5>;
> +			st,mode = "HDMI";
> +		};
> +
> +		sti_uni_player1: sti-uni-player@1 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
assigned-clocks = <&clk_s_d0_quadfs 1>, <&clk_s_d0_flexgen CLK_PCM_1>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 1>;

> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D81000 0x158>;
> +			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 3 0 1>;
> +			dai-name = "Uni Player #1 (PIO)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <1>;
> +			st,version = <5>;
> +			st,mode = "PCM";
> +		};
> +
> +		sti_uni_player2: sti-uni-player@2 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
assigned-clocks = <&clk_s_d0_quadfs 2>, <&clk_s_d0_flexgen CLK_PCM_2>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 2>;
> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D82000 0x158>;
> +			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 4 0 1>;
> +			dai-name = "Uni Player #1 (DAC)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <2>;
> +			st,version = <5>;
> +			st,mode = "PCM";
> +		};
> +
> +		sti_uni_player3: sti-uni-player@3 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
> +			assigned-clock-rates = <50000000>;
assigned-clocks = <&clk_s_d0_quadfs 3>, <&clk_s_d0_flexgen CLK_SPDIFF>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 3>;

Regards,
Arnaud
> +			reg = <0x8D85000 0x158>;
> +			interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 7 0 1>;
> +			dma-names = "tx";
> +			dai-name = "Uni Player #1 (PIO)";
> +			st,uniperiph-id = <3>;
> +			st,version = <5>;
> +			st,mode = "SPDIF";
> +		};
>  	};
>  };
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
@ 2016-05-31  9:14     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:14 UTC (permalink / raw)
  To: linux-arm-kernel



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the DT nodes for the uniperif player
> IP blocks found on STiH407 family silicon.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 60f95b6..7ca149b 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -755,5 +755,81 @@
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&pinctrl_spdif_out >;
>  		};
> +
> +		sti_uni_player0: sti-uni-player at 0 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
This does not work properly. You need to declare parent like this:
assigned-clocks = <&clk_s_d0_quadfs 0>, <&clk_s_d0_flexgen CLK_PCM_0>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 0>;

> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D80000 0x158>;
> +			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 2 0 1>;
> +			dai-name = "Uni Player #0 (HDMI)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <0>;
> +			st,version = <5>;
> +			st,mode = "HDMI";
> +		};
> +
> +		sti_uni_player1: sti-uni-player at 1 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
assigned-clocks = <&clk_s_d0_quadfs 1>, <&clk_s_d0_flexgen CLK_PCM_1>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 1>;

> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D81000 0x158>;
> +			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 3 0 1>;
> +			dai-name = "Uni Player #1 (PIO)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <1>;
> +			st,version = <5>;
> +			st,mode = "PCM";
> +		};
> +
> +		sti_uni_player2: sti-uni-player at 2 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
assigned-clocks = <&clk_s_d0_quadfs 2>, <&clk_s_d0_flexgen CLK_PCM_2>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 2>;
> +			assigned-clock-rates = <50000000>;
> +			reg = <0x8D82000 0x158>;
> +			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 4 0 1>;
> +			dai-name = "Uni Player #1 (DAC)";
> +			dma-names = "tx";
> +			st,uniperiph-id = <2>;
> +			st,version = <5>;
> +			st,mode = "PCM";
> +		};
> +
> +		sti_uni_player3: sti-uni-player at 3 {
> +			compatible = "st,sti-uni-player";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> +			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> +			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
> +			assigned-clock-rates = <50000000>;
assigned-clocks = <&clk_s_d0_quadfs 3>, <&clk_s_d0_flexgen CLK_SPDIFF>;
assigned-clock-parents = <0>, <&clk_s_d0_quadfs 3>;

Regards,
Arnaud
> +			reg = <0x8D85000 0x158>;
> +			interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 7 0 1>;
> +			dma-names = "tx";
> +			dai-name = "Uni Player #1 (PIO)";
> +			st,uniperiph-id = <3>;
> +			st,version = <5>;
> +			st,mode = "SPDIF";
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader dt nodes
  2016-05-25 16:06   ` Peter Griffin
  (?)
@ 2016-05-31  9:18     ` Arnaud Pouliquen
  -1 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:18 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the DT node for the uniperif reader
> IP block found on STiH407 family silicon.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 7ca149b..fb6363e1 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -831,5 +831,33 @@
>  			st,version = <5>;
>  			st,mode = "SPDIF";
>  		};
> +
> +		sti_uni_reader0: sti-uni-reader@0 {
> +			compatible = "st,sti-uni-reader";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			reg = <0x8D83000 0x158>;
> +			interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 5 0 1>;
> +			dma-names = "rx";
> +			dai-name = "Uni Reader #0 (PCM IN)";
> +			st,version = <3>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_i2s_8ch_in>;
suppress pinctrl declaration
> +		};
> +
> +		sti_uni_reader1: sti-uni-reader@1 {
> +			compatible = "st,sti-uni-reader";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			reg = <0x8D84000 0x158>;
> +			interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 6 0 1>;
> +			dma-names = "rx";
> +			dai-name = "Uni Reader #1 (HDMI RX)";
> +			st,version = <3>;
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader dt nodes
@ 2016-05-31  9:18     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:18 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the DT node for the uniperif reader
> IP block found on STiH407 family silicon.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 7ca149b..fb6363e1 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -831,5 +831,33 @@
>  			st,version = <5>;
>  			st,mode = "SPDIF";
>  		};
> +
> +		sti_uni_reader0: sti-uni-reader@0 {
> +			compatible = "st,sti-uni-reader";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			reg = <0x8D83000 0x158>;
> +			interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 5 0 1>;
> +			dma-names = "rx";
> +			dai-name = "Uni Reader #0 (PCM IN)";
> +			st,version = <3>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_i2s_8ch_in>;
suppress pinctrl declaration
> +		};
> +
> +		sti_uni_reader1: sti-uni-reader@1 {
> +			compatible = "st,sti-uni-reader";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			reg = <0x8D84000 0x158>;
> +			interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 6 0 1>;
> +			dma-names = "rx";
> +			dai-name = "Uni Reader #1 (HDMI RX)";
> +			st,version = <3>;
> +		};
>  	};
>  };
> 

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

* [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader dt nodes
@ 2016-05-31  9:18     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31  9:18 UTC (permalink / raw)
  To: linux-arm-kernel



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch adds the DT node for the uniperif reader
> IP block found on STiH407 family silicon.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 7ca149b..fb6363e1 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -831,5 +831,33 @@
>  			st,version = <5>;
>  			st,mode = "SPDIF";
>  		};
> +
> +		sti_uni_reader0: sti-uni-reader at 0 {
> +			compatible = "st,sti-uni-reader";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			reg = <0x8D83000 0x158>;
> +			interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 5 0 1>;
> +			dma-names = "rx";
> +			dai-name = "Uni Reader #0 (PCM IN)";
> +			st,version = <3>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_i2s_8ch_in>;
suppress pinctrl declaration
> +		};
> +
> +		sti_uni_reader1: sti-uni-reader at 1 {
> +			compatible = "st,sti-uni-reader";
> +			status = "disabled";
> +			#sound-dai-cells = <0>;
> +			st,syscfg = <&syscfg_core>;
> +			reg = <0x8D84000 0x158>;
> +			interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
> +			dmas = <&fdma0 6 0 1>;
> +			dma-names = "rx";
> +			dai-name = "Uni Reader #1 (HDMI RX)";
> +			st,version = <3>;
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 18/18] ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
  2016-05-25 16:06   ` Peter Griffin
  (?)
@ 2016-05-31 10:16     ` Arnaud Pouliquen
  -1 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31 10:16 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch enables the uniperif players 2 & 3 for b2120 boards
> and also adds the "simple-audio-card" device node to interconnect
> the SoC sound device and the codec.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi | 40 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index 722c63f..5297f21 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -131,5 +131,45 @@
>  				dvb-card	= <STV0367_TDA18212_NIMA_1>;
>  			};
>  		};
> +
> +		sti_uni_player2: sti-uni-player@2 {
> +			status = "okay";
> +		};
> +
> +		sti_uni_player3: sti-uni-player@3 {
> +			status = "okay";
> +		};
enable sti-sasg-codec with spdif pinctrl
> +
> +		sound {
> +			compatible = "simple-audio-card";
> +			simple-audio-card,name = "sti audio card";
> +			status = "okay";
> +
> +			simple-audio-card,dai-link@0 {
> +				/* DAC */
> +				format = "i2s";
> +				dai-tdm-slot-width = <32>;
clean dai-tdm-slot-width, not used.

Regards,
Arnaud
> +				mclk-fs = <256>;
> +				cpu {
> +					sound-dai = <&sti_uni_player2>;
> +				};
> +
> +				codec {
> +					sound-dai = <&sti_sasg_codec 1>;
> +				};
> +			};
> +			simple-audio-card,dai-link@1 {
> +				/* SPDIF */
> +				format = "left_j";
> +				mclk-fs = <128>;
> +				cpu {
> +					sound-dai = <&sti_uni_player3>;
> +				};
> +
> +				codec {
> +					sound-dai = <&sti_sasg_codec 0>;
> +				};
> +			};
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 18/18] ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
@ 2016-05-31 10:16     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31 10:16 UTC (permalink / raw)
  To: Peter Griffin, linux-arm-kernel, linux-kernel,
	srinivas.kandagatla, maxime.coquelin, patrice.chotard,
	vinod.koul, ohad, bjorn.andersson, arnd
  Cc: lee.jones, devicetree, dmaengine, linux-remoteproc



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch enables the uniperif players 2 & 3 for b2120 boards
> and also adds the "simple-audio-card" device node to interconnect
> the SoC sound device and the codec.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi | 40 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index 722c63f..5297f21 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -131,5 +131,45 @@
>  				dvb-card	= <STV0367_TDA18212_NIMA_1>;
>  			};
>  		};
> +
> +		sti_uni_player2: sti-uni-player@2 {
> +			status = "okay";
> +		};
> +
> +		sti_uni_player3: sti-uni-player@3 {
> +			status = "okay";
> +		};
enable sti-sasg-codec with spdif pinctrl
> +
> +		sound {
> +			compatible = "simple-audio-card";
> +			simple-audio-card,name = "sti audio card";
> +			status = "okay";
> +
> +			simple-audio-card,dai-link@0 {
> +				/* DAC */
> +				format = "i2s";
> +				dai-tdm-slot-width = <32>;
clean dai-tdm-slot-width, not used.

Regards,
Arnaud
> +				mclk-fs = <256>;
> +				cpu {
> +					sound-dai = <&sti_uni_player2>;
> +				};
> +
> +				codec {
> +					sound-dai = <&sti_sasg_codec 1>;
> +				};
> +			};
> +			simple-audio-card,dai-link@1 {
> +				/* SPDIF */
> +				format = "left_j";
> +				mclk-fs = <128>;
> +				cpu {
> +					sound-dai = <&sti_uni_player3>;
> +				};
> +
> +				codec {
> +					sound-dai = <&sti_sasg_codec 0>;
> +				};
> +			};
> +		};
>  	};
>  };
> 

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

* [PATCH v4 18/18] ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
@ 2016-05-31 10:16     ` Arnaud Pouliquen
  0 siblings, 0 replies; 113+ messages in thread
From: Arnaud Pouliquen @ 2016-05-31 10:16 UTC (permalink / raw)
  To: linux-arm-kernel



On 05/25/2016 06:06 PM, Peter Griffin wrote:
> This patch enables the uniperif players 2 & 3 for b2120 boards
> and also adds the "simple-audio-card" device node to interconnect
> the SoC sound device and the codec.
> 
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi | 40 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index 722c63f..5297f21 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -131,5 +131,45 @@
>  				dvb-card	= <STV0367_TDA18212_NIMA_1>;
>  			};
>  		};
> +
> +		sti_uni_player2: sti-uni-player at 2 {
> +			status = "okay";
> +		};
> +
> +		sti_uni_player3: sti-uni-player at 3 {
> +			status = "okay";
> +		};
enable sti-sasg-codec with spdif pinctrl
> +
> +		sound {
> +			compatible = "simple-audio-card";
> +			simple-audio-card,name = "sti audio card";
> +			status = "okay";
> +
> +			simple-audio-card,dai-link at 0 {
> +				/* DAC */
> +				format = "i2s";
> +				dai-tdm-slot-width = <32>;
clean dai-tdm-slot-width, not used.

Regards,
Arnaud
> +				mclk-fs = <256>;
> +				cpu {
> +					sound-dai = <&sti_uni_player2>;
> +				};
> +
> +				codec {
> +					sound-dai = <&sti_sasg_codec 1>;
> +				};
> +			};
> +			simple-audio-card,dai-link at 1 {
> +				/* SPDIF */
> +				format = "left_j";
> +				mclk-fs = <128>;
> +				cpu {
> +					sound-dai = <&sti_uni_player3>;
> +				};
> +
> +				codec {
> +					sound-dai = <&sti_sasg_codec 0>;
> +				};
> +			};
> +		};
>  	};
>  };
> 

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

* Re: [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
@ 2016-06-03 12:39       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:39 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, lee.jones, devicetree, dmaengine,
	linux-remoteproc, broonie

Hi Arnaud,

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> Hi Peter,
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch enables the STi ALSA drivers found on STi platforms
> > as well as the simple-card driver which is a dependency to have
> > working sound.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > Cc: arnaud.pouliquen@st.com
> > Cc: broonie@kernel.org
> > ---
> >  arch/arm/configs/multi_v7_defconfig | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> > index 5eee45b..0ced665 100644
> > --- a/arch/arm/configs/multi_v7_defconfig
> > +++ b/arch/arm/configs/multi_v7_defconfig
> > @@ -589,6 +589,9 @@ CONFIG_SND_SOC_AK4642=m
> >  CONFIG_SND_SOC_SGTL5000=m
> >  CONFIG_SND_SOC_SPDIF=m
> >  CONFIG_SND_SOC_WM8978=m
> > +CONFIG_SND_SOC_STI=m
> > +CONFIG_SND_SOC_STI_SAS=m
> > +CONFIG_SND_SIMPLE_CARD=m
> Simple card config seems enabled by default, at least on 4.7 rc1.

I don't think it is currently, I get the following when greping v4.7-rc1 tag

git grep CONFIG_SND_SIMPLE_CARD
arch/arm/configs/exynos_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/imx_v6_v7_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/multi_v5_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/mvebu_v5_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/mvebu_v7_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/omap2plus_defconfig:CONFIG_SND_SIMPLE_CARD=m
arch/arm/configs/pxa_defconfig:CONFIG_SND_SIMPLE_CARD=m
arch/xtensa/configs/audio_kc705_defconfig:CONFIG_SND_SIMPLE_CARD=y
sound/soc/generic/Makefile:obj-$(CONFIG_SND_SIMPLE_CARD)        +=
snd-soc-simple-card.o

Although maybe it should be built-in rather than a module, like multi_v5_defconfig.

regards,

Peter

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

* Re: [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
@ 2016-06-03 12:39       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:39 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA,
	broonie-DgEjT+Ai2ygdnm+yROfE0A

Hi Arnaud,

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> Hi Peter,
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch enables the STi ALSA drivers found on STi platforms
> > as well as the simple-card driver which is a dependency to have
> > working sound.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > Cc: arnaud.pouliquen-qxv4g6HH51o@public.gmane.org
> > Cc: broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
> > ---
> >  arch/arm/configs/multi_v7_defconfig | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> > index 5eee45b..0ced665 100644
> > --- a/arch/arm/configs/multi_v7_defconfig
> > +++ b/arch/arm/configs/multi_v7_defconfig
> > @@ -589,6 +589,9 @@ CONFIG_SND_SOC_AK4642=m
> >  CONFIG_SND_SOC_SGTL5000=m
> >  CONFIG_SND_SOC_SPDIF=m
> >  CONFIG_SND_SOC_WM8978=m
> > +CONFIG_SND_SOC_STI=m
> > +CONFIG_SND_SOC_STI_SAS=m
> > +CONFIG_SND_SIMPLE_CARD=m
> Simple card config seems enabled by default, at least on 4.7 rc1.

I don't think it is currently, I get the following when greping v4.7-rc1 tag

git grep CONFIG_SND_SIMPLE_CARD
arch/arm/configs/exynos_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/imx_v6_v7_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/multi_v5_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/mvebu_v5_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/mvebu_v7_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/omap2plus_defconfig:CONFIG_SND_SIMPLE_CARD=m
arch/arm/configs/pxa_defconfig:CONFIG_SND_SIMPLE_CARD=m
arch/xtensa/configs/audio_kc705_defconfig:CONFIG_SND_SIMPLE_CARD=y
sound/soc/generic/Makefile:obj-$(CONFIG_SND_SIMPLE_CARD)        +=
snd-soc-simple-card.o

Although maybe it should be built-in rather than a module, like multi_v5_defconfig.

regards,

Peter
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
@ 2016-06-03 12:39       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnaud,

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> Hi Peter,
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch enables the STi ALSA drivers found on STi platforms
> > as well as the simple-card driver which is a dependency to have
> > working sound.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > Cc: arnaud.pouliquen at st.com
> > Cc: broonie at kernel.org
> > ---
> >  arch/arm/configs/multi_v7_defconfig | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> > index 5eee45b..0ced665 100644
> > --- a/arch/arm/configs/multi_v7_defconfig
> > +++ b/arch/arm/configs/multi_v7_defconfig
> > @@ -589,6 +589,9 @@ CONFIG_SND_SOC_AK4642=m
> >  CONFIG_SND_SOC_SGTL5000=m
> >  CONFIG_SND_SOC_SPDIF=m
> >  CONFIG_SND_SOC_WM8978=m
> > +CONFIG_SND_SOC_STI=m
> > +CONFIG_SND_SOC_STI_SAS=m
> > +CONFIG_SND_SIMPLE_CARD=m
> Simple card config seems enabled by default, at least on 4.7 rc1.

I don't think it is currently, I get the following when greping v4.7-rc1 tag

git grep CONFIG_SND_SIMPLE_CARD
arch/arm/configs/exynos_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/imx_v6_v7_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/multi_v5_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/mvebu_v5_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/mvebu_v7_defconfig:CONFIG_SND_SIMPLE_CARD=y
arch/arm/configs/omap2plus_defconfig:CONFIG_SND_SIMPLE_CARD=m
arch/arm/configs/pxa_defconfig:CONFIG_SND_SIMPLE_CARD=m
arch/xtensa/configs/audio_kc705_defconfig:CONFIG_SND_SIMPLE_CARD=y
sound/soc/generic/Makefile:obj-$(CONFIG_SND_SIMPLE_CARD)        +=
snd-soc-simple-card.o

Although maybe it should be built-in rather than a module, like multi_v5_defconfig.

regards,

Peter

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

* Re: [PATCH v4 18/18] ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
  2016-05-31 10:16     ` Arnaud Pouliquen
@ 2016-06-03 12:47       ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:47 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, lee.jones, devicetree, dmaengine,
	linux-remoteproc

Hi Arnaud,

Thanks for reviewing.

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch enables the uniperif players 2 & 3 for b2120 boards
> > and also adds the "simple-audio-card" device node to interconnect
> > the SoC sound device and the codec.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > ---
> >  arch/arm/boot/dts/stihxxx-b2120.dtsi | 40 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 40 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > index 722c63f..5297f21 100644
> > --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > @@ -131,5 +131,45 @@
> >  				dvb-card	= <STV0367_TDA18212_NIMA_1>;
> >  			};
> >  		};
> > +
> > +		sti_uni_player2: sti-uni-player@2 {
> > +			status = "okay";
> > +		};
> > +
> > +		sti_uni_player3: sti-uni-player@3 {
> > +			status = "okay";
> > +		};
> enable sti-sasg-codec with spdif pinctrl

Will fix in v5

> > +
> > +		sound {
> > +			compatible = "simple-audio-card";
> > +			simple-audio-card,name = "sti audio card";
> > +			status = "okay";
> > +
> > +			simple-audio-card,dai-link@0 {
> > +				/* DAC */
> > +				format = "i2s";
> > +				dai-tdm-slot-width = <32>;
> clean dai-tdm-slot-width, not used.

Will fix in v5

regards,

Peter.

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

* [PATCH v4 18/18] ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
@ 2016-06-03 12:47       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnaud,

Thanks for reviewing.

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch enables the uniperif players 2 & 3 for b2120 boards
> > and also adds the "simple-audio-card" device node to interconnect
> > the SoC sound device and the codec.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > ---
> >  arch/arm/boot/dts/stihxxx-b2120.dtsi | 40 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 40 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > index 722c63f..5297f21 100644
> > --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > @@ -131,5 +131,45 @@
> >  				dvb-card	= <STV0367_TDA18212_NIMA_1>;
> >  			};
> >  		};
> > +
> > +		sti_uni_player2: sti-uni-player at 2 {
> > +			status = "okay";
> > +		};
> > +
> > +		sti_uni_player3: sti-uni-player at 3 {
> > +			status = "okay";
> > +		};
> enable sti-sasg-codec with spdif pinctrl

Will fix in v5

> > +
> > +		sound {
> > +			compatible = "simple-audio-card";
> > +			simple-audio-card,name = "sti audio card";
> > +			status = "okay";
> > +
> > +			simple-audio-card,dai-link at 0 {
> > +				/* DAC */
> > +				format = "i2s";
> > +				dai-tdm-slot-width = <32>;
> clean dai-tdm-slot-width, not used.

Will fix in v5

regards,

Peter.

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

* Re: [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader dt nodes
@ 2016-06-03 12:50       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:50 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, lee.jones, devicetree, dmaengine,
	linux-remoteproc

Hi Arnaud,

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch adds the DT node for the uniperif reader
> > IP block found on STiH407 family silicon.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > ---
> >  arch/arm/boot/dts/stih407-family.dtsi | 28 ++++++++++++++++++++++++++++
> >  1 file changed, 28 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> > index 7ca149b..fb6363e1 100644
> > --- a/arch/arm/boot/dts/stih407-family.dtsi
> > +++ b/arch/arm/boot/dts/stih407-family.dtsi
> > @@ -831,5 +831,33 @@
> >  			st,version = <5>;
> >  			st,mode = "SPDIF";
> >  		};
> > +
> > +		sti_uni_reader0: sti-uni-reader@0 {
> > +			compatible = "st,sti-uni-reader";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			reg = <0x8D83000 0x158>;
> > +			interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 5 0 1>;
> > +			dma-names = "rx";
> > +			dai-name = "Uni Reader #0 (PCM IN)";
> > +			st,version = <3>;
> > +			pinctrl-names = "default";
> > +			pinctrl-0 = <&pinctrl_i2s_8ch_in>;
> suppress pinctrl declaration

Will fix in v5

regards,

Peter.

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

* Re: [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader dt nodes
@ 2016-06-03 12:50       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:50 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA

Hi Arnaud,

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch adds the DT node for the uniperif reader
> > IP block found on STiH407 family silicon.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > ---
> >  arch/arm/boot/dts/stih407-family.dtsi | 28 ++++++++++++++++++++++++++++
> >  1 file changed, 28 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> > index 7ca149b..fb6363e1 100644
> > --- a/arch/arm/boot/dts/stih407-family.dtsi
> > +++ b/arch/arm/boot/dts/stih407-family.dtsi
> > @@ -831,5 +831,33 @@
> >  			st,version = <5>;
> >  			st,mode = "SPDIF";
> >  		};
> > +
> > +		sti_uni_reader0: sti-uni-reader@0 {
> > +			compatible = "st,sti-uni-reader";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			reg = <0x8D83000 0x158>;
> > +			interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 5 0 1>;
> > +			dma-names = "rx";
> > +			dai-name = "Uni Reader #0 (PCM IN)";
> > +			st,version = <3>;
> > +			pinctrl-names = "default";
> > +			pinctrl-0 = <&pinctrl_i2s_8ch_in>;
> suppress pinctrl declaration

Will fix in v5

regards,

Peter.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader dt nodes
@ 2016-06-03 12:50       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnaud,

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch adds the DT node for the uniperif reader
> > IP block found on STiH407 family silicon.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > ---
> >  arch/arm/boot/dts/stih407-family.dtsi | 28 ++++++++++++++++++++++++++++
> >  1 file changed, 28 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> > index 7ca149b..fb6363e1 100644
> > --- a/arch/arm/boot/dts/stih407-family.dtsi
> > +++ b/arch/arm/boot/dts/stih407-family.dtsi
> > @@ -831,5 +831,33 @@
> >  			st,version = <5>;
> >  			st,mode = "SPDIF";
> >  		};
> > +
> > +		sti_uni_reader0: sti-uni-reader at 0 {
> > +			compatible = "st,sti-uni-reader";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			reg = <0x8D83000 0x158>;
> > +			interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 5 0 1>;
> > +			dma-names = "rx";
> > +			dai-name = "Uni Reader #0 (PCM IN)";
> > +			st,version = <3>;
> > +			pinctrl-names = "default";
> > +			pinctrl-0 = <&pinctrl_i2s_8ch_in>;
> suppress pinctrl declaration

Will fix in v5

regards,

Peter.

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

* Re: [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
  2016-05-31  9:14     ` Arnaud Pouliquen
@ 2016-06-03 12:56       ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:56 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, lee.jones, devicetree, dmaengine,
	linux-remoteproc

Hi Arnaud,

Thanks for reviewing.

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch adds the DT nodes for the uniperif player
> > IP blocks found on STiH407 family silicon.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > ---
> >  arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
> >  1 file changed, 76 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> > index 60f95b6..7ca149b 100644
> > --- a/arch/arm/boot/dts/stih407-family.dtsi
> > +++ b/arch/arm/boot/dts/stih407-family.dtsi
> > @@ -755,5 +755,81 @@
> >  			pinctrl-names = "default";
> >  			pinctrl-0 = <&pinctrl_spdif_out >;
> >  		};
> > +
> > +		sti_uni_player0: sti-uni-player@0 {
> > +			compatible = "st,sti-uni-player";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> > +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> > +			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
> This does not work properly. You need to declare parent like this:
> assigned-clocks = <&clk_s_d0_quadfs 0>, <&clk_s_d0_flexgen CLK_PCM_0>;
> assigned-clock-parents = <0>, <&clk_s_d0_quadfs 0>;

Will fix in v5

> 
> > +			assigned-clock-rates = <50000000>;
> > +			reg = <0x8D80000 0x158>;
> > +			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 2 0 1>;
> > +			dai-name = "Uni Player #0 (HDMI)";
> > +			dma-names = "tx";
> > +			st,uniperiph-id = <0>;
> > +			st,version = <5>;
> > +			st,mode = "HDMI";
> > +		};
> > +
> > +		sti_uni_player1: sti-uni-player@1 {
> > +			compatible = "st,sti-uni-player";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> > +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> > +			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
> assigned-clocks = <&clk_s_d0_quadfs 1>, <&clk_s_d0_flexgen CLK_PCM_1>;
> assigned-clock-parents = <0>, <&clk_s_d0_quadfs 1>;

Will fix in v5

> 
> > +			assigned-clock-rates = <50000000>;
> > +			reg = <0x8D81000 0x158>;
> > +			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 3 0 1>;
> > +			dai-name = "Uni Player #1 (PIO)";
> > +			dma-names = "tx";
> > +			st,uniperiph-id = <1>;
> > +			st,version = <5>;
> > +			st,mode = "PCM";
> > +		};
> > +
> > +		sti_uni_player2: sti-uni-player@2 {
> > +			compatible = "st,sti-uni-player";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> > +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> > +			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
> assigned-clocks = <&clk_s_d0_quadfs 2>, <&clk_s_d0_flexgen CLK_PCM_2>;
> assigned-clock-parents = <0>, <&clk_s_d0_quadfs 2>;

Will fix in v5

> > +			assigned-clock-rates = <50000000>;
> > +			reg = <0x8D82000 0x158>;
> > +			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 4 0 1>;
> > +			dai-name = "Uni Player #1 (DAC)";
> > +			dma-names = "tx";
> > +			st,uniperiph-id = <2>;
> > +			st,version = <5>;
> > +			st,mode = "PCM";
> > +		};
> > +
> > +		sti_uni_player3: sti-uni-player@3 {
> > +			compatible = "st,sti-uni-player";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> > +			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> > +			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
> > +			assigned-clock-rates = <50000000>;
> assigned-clocks = <&clk_s_d0_quadfs 3>, <&clk_s_d0_flexgen CLK_SPDIFF>;
> assigned-clock-parents = <0>, <&clk_s_d0_quadfs 3>;

Will fix in v5

Regards,

Peter.

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

* [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes
@ 2016-06-03 12:56       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 12:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnaud,

Thanks for reviewing.

On Tue, 31 May 2016, Arnaud Pouliquen wrote:

> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch adds the DT nodes for the uniperif player
> > IP blocks found on STiH407 family silicon.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > ---
> >  arch/arm/boot/dts/stih407-family.dtsi | 76 +++++++++++++++++++++++++++++++++++
> >  1 file changed, 76 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> > index 60f95b6..7ca149b 100644
> > --- a/arch/arm/boot/dts/stih407-family.dtsi
> > +++ b/arch/arm/boot/dts/stih407-family.dtsi
> > @@ -755,5 +755,81 @@
> >  			pinctrl-names = "default";
> >  			pinctrl-0 = <&pinctrl_spdif_out >;
> >  		};
> > +
> > +		sti_uni_player0: sti-uni-player at 0 {
> > +			compatible = "st,sti-uni-player";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> > +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
> > +			assigned-clock-parents = <&clk_s_d0_quadfs 0>;
> This does not work properly. You need to declare parent like this:
> assigned-clocks = <&clk_s_d0_quadfs 0>, <&clk_s_d0_flexgen CLK_PCM_0>;
> assigned-clock-parents = <0>, <&clk_s_d0_quadfs 0>;

Will fix in v5

> 
> > +			assigned-clock-rates = <50000000>;
> > +			reg = <0x8D80000 0x158>;
> > +			interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 2 0 1>;
> > +			dai-name = "Uni Player #0 (HDMI)";
> > +			dma-names = "tx";
> > +			st,uniperiph-id = <0>;
> > +			st,version = <5>;
> > +			st,mode = "HDMI";
> > +		};
> > +
> > +		sti_uni_player1: sti-uni-player at 1 {
> > +			compatible = "st,sti-uni-player";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> > +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
> > +			assigned-clock-parents = <&clk_s_d0_quadfs 1>;
> assigned-clocks = <&clk_s_d0_quadfs 1>, <&clk_s_d0_flexgen CLK_PCM_1>;
> assigned-clock-parents = <0>, <&clk_s_d0_quadfs 1>;

Will fix in v5

> 
> > +			assigned-clock-rates = <50000000>;
> > +			reg = <0x8D81000 0x158>;
> > +			interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 3 0 1>;
> > +			dai-name = "Uni Player #1 (PIO)";
> > +			dma-names = "tx";
> > +			st,uniperiph-id = <1>;
> > +			st,version = <5>;
> > +			st,mode = "PCM";
> > +		};
> > +
> > +		sti_uni_player2: sti-uni-player at 2 {
> > +			compatible = "st,sti-uni-player";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> > +			assigned-clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
> > +			assigned-clock-parents = <&clk_s_d0_quadfs 2>;
> assigned-clocks = <&clk_s_d0_quadfs 2>, <&clk_s_d0_flexgen CLK_PCM_2>;
> assigned-clock-parents = <0>, <&clk_s_d0_quadfs 2>;

Will fix in v5

> > +			assigned-clock-rates = <50000000>;
> > +			reg = <0x8D82000 0x158>;
> > +			interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
> > +			dmas = <&fdma0 4 0 1>;
> > +			dai-name = "Uni Player #1 (DAC)";
> > +			dma-names = "tx";
> > +			st,uniperiph-id = <2>;
> > +			st,version = <5>;
> > +			st,mode = "PCM";
> > +		};
> > +
> > +		sti_uni_player3: sti-uni-player at 3 {
> > +			compatible = "st,sti-uni-player";
> > +			status = "disabled";
> > +			#sound-dai-cells = <0>;
> > +			st,syscfg = <&syscfg_core>;
> > +			clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> > +			assigned-clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
> > +			assigned-clock-parents = <&clk_s_d0_quadfs 3>;
> > +			assigned-clock-rates = <50000000>;
> assigned-clocks = <&clk_s_d0_quadfs 3>, <&clk_s_d0_flexgen CLK_SPDIFF>;
> assigned-clock-parents = <0>, <&clk_s_d0_quadfs 3>;

Will fix in v5

Regards,

Peter.

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

* Re: [PATCH v4 15/18] ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
  2016-05-31  9:05     ` Arnaud Pouliquen
@ 2016-06-03 13:00       ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 13:00 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, lee.jones, devicetree, dmaengine,
	linux-remoteproc

Hi Arnaud,

Thanks for reviewing.

On Tue, 31 May 2016, Arnaud Pouliquen wrote:
> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch adds the dt node for the internal audio
> > codec IP.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > ---
> >  arch/arm/boot/dts/stih407-family.dtsi | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> > index b423836..60f95b6 100644
> > --- a/arch/arm/boot/dts/stih407-family.dtsi
> > +++ b/arch/arm/boot/dts/stih407-family.dtsi
> > @@ -746,5 +746,14 @@
> >  				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
> >  				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
> >  		};
> > +
> > +		sti_sasg_codec: sti-sasg-codec {
> > +			compatible = "st,stih407-sas-codec";
> > +			#sound-dai-cells = <1>;
> > +			status = "okay";
> Should be set to disable in family and enabled it depending on boards
> (stihxxx-b2120.dtsi)

Will fix in v5

> > +			st,syscfg = <&syscfg_core>;
> > +			pinctrl-names = "default";
> > +			pinctrl-0 = <&pinctrl_spdif_out >;
> Declare pinctrl use in stihxxx-b2120.dtsi, should be set only if SPDIF used.

Will fix in v5

regards,

Peter.

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

* [PATCH v4 15/18] ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
@ 2016-06-03 13:00       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 13:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnaud,

Thanks for reviewing.

On Tue, 31 May 2016, Arnaud Pouliquen wrote:
> 
> 
> On 05/25/2016 06:06 PM, Peter Griffin wrote:
> > This patch adds the dt node for the internal audio
> > codec IP.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> > ---
> >  arch/arm/boot/dts/stih407-family.dtsi | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> > index b423836..60f95b6 100644
> > --- a/arch/arm/boot/dts/stih407-family.dtsi
> > +++ b/arch/arm/boot/dts/stih407-family.dtsi
> > @@ -746,5 +746,14 @@
> >  				<&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
> >  				<&clk_s_c0_flexgen CLK_EXT2F_A9>;
> >  		};
> > +
> > +		sti_sasg_codec: sti-sasg-codec {
> > +			compatible = "st,stih407-sas-codec";
> > +			#sound-dai-cells = <1>;
> > +			status = "okay";
> Should be set to disable in family and enabled it depending on boards
> (stihxxx-b2120.dtsi)

Will fix in v5

> > +			st,syscfg = <&syscfg_core>;
> > +			pinctrl-names = "default";
> > +			pinctrl-0 = <&pinctrl_spdif_out >;
> Declare pinctrl use in stihxxx-b2120.dtsi, should be set only if SPDIF used.

Will fix in v5

regards,

Peter.

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

* Re: [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
  2016-05-27 17:14     ` Mark Brown
@ 2016-06-03 13:05       ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 13:05 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad,
	bjorn.andersson, arnd, lee.jones, devicetree, dmaengine,
	linux-remoteproc, arnaud.pouliquen

Hi Mark,

On Fri, 27 May 2016, Mark Brown wrote:

> On Wed, May 25, 2016 at 05:06:44PM +0100, Peter Griffin wrote:
> > uniperiph-id, version and mode are ST specific bindings and
> > need the 'st,' prefix. Update the examples, as otherwise copying
> > them yields a runtime error parsing the DT node.
> 
> You've not copied me on the rest of the series so I've no idea what's
> going on with dependencies.  When sending a patch series it is important
> to ensure that all the various maintainers understand what the
> relationship between the patches as the expecation is that there will be
> interdependencies.  Either copy everyone on the whole series or at least
> copy them on the cover letter and explain what's going on.  If there are
> no strong interdependencies then it's generally simplest to just send
> the patches separately to avoid any possible confusion.

Ok will bare this in mind for v5 series.

Regards,

Peter.

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

* [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code
@ 2016-06-03 13:05       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-03 13:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

On Fri, 27 May 2016, Mark Brown wrote:

> On Wed, May 25, 2016 at 05:06:44PM +0100, Peter Griffin wrote:
> > uniperiph-id, version and mode are ST specific bindings and
> > need the 'st,' prefix. Update the examples, as otherwise copying
> > them yields a runtime error parsing the DT node.
> 
> You've not copied me on the rest of the series so I've no idea what's
> going on with dependencies.  When sending a patch series it is important
> to ensure that all the various maintainers understand what the
> relationship between the patches as the expecation is that there will be
> interdependencies.  Either copy everyone on the whole series or at least
> copy them on the cover letter and explain what's going on.  If there are
> no strong interdependencies then it's generally simplest to just send
> the patches separately to avoid any possible confusion.

Ok will bare this in mind for v5 series.

Regards,

Peter.

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

* Re: [PATCH v4 05/18] dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
  2016-05-25 16:06   ` Peter Griffin
@ 2016-06-06  4:36     ` Vinod Koul
  -1 siblings, 0 replies; 113+ messages in thread
From: Vinod Koul @ 2016-06-06  4:36 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, ohad, bjorn.andersson, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc,
	Ludovic Barre

On Wed, May 25, 2016 at 05:06:39PM +0100, Peter Griffin wrote:

> +/*
> + * request control bits
> + */
> +#define REQ_CTRL_NUM_OPS_MASK		GENMASK(31, 24)
> +#define REQ_CTRL_NUM_OPS(n)		(REQ_CTRL_NUM_OPS_MASK & ((n) << 24))
> +#define REQ_CTRL_INITIATOR_MASK		BIT(22)
> +#define	REQ_CTRL_INIT0			(0x0 << 22)
> +#define	REQ_CTRL_INIT1			(0x1 << 22)

pls keep spaces or tabs, not both :(

> +#define REQ_CTRL_INC_ADDR_ON		BIT(21)
> +#define REQ_CTRL_DATA_SWAP_ON		BIT(17)
> +#define REQ_CTRL_WNR			BIT(14)
> +#define REQ_CTRL_OPCODE_MASK		GENMASK(7, 4)
> +#define REQ_CTRL_OPCODE_LD_ST1		(0x0 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST2		(0x1 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST4		(0x2 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST8		(0x3 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST16		(0x4 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST32		(0x5 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST64		(0x6 << 4)
> +#define REQ_CTRL_HOLDOFF_MASK		GENMASK(2, 0)
> +#define REQ_CTRL_HOLDOFF(n)		((n) & REQ_CTRL_HOLDOFF_MASK)

Everything here is FDMA_ so why not these as well

-- 
~Vinod

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

* [PATCH v4 05/18] dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
@ 2016-06-06  4:36     ` Vinod Koul
  0 siblings, 0 replies; 113+ messages in thread
From: Vinod Koul @ 2016-06-06  4:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 25, 2016 at 05:06:39PM +0100, Peter Griffin wrote:

> +/*
> + * request control bits
> + */
> +#define REQ_CTRL_NUM_OPS_MASK		GENMASK(31, 24)
> +#define REQ_CTRL_NUM_OPS(n)		(REQ_CTRL_NUM_OPS_MASK & ((n) << 24))
> +#define REQ_CTRL_INITIATOR_MASK		BIT(22)
> +#define	REQ_CTRL_INIT0			(0x0 << 22)
> +#define	REQ_CTRL_INIT1			(0x1 << 22)

pls keep spaces or tabs, not both :(

> +#define REQ_CTRL_INC_ADDR_ON		BIT(21)
> +#define REQ_CTRL_DATA_SWAP_ON		BIT(17)
> +#define REQ_CTRL_WNR			BIT(14)
> +#define REQ_CTRL_OPCODE_MASK		GENMASK(7, 4)
> +#define REQ_CTRL_OPCODE_LD_ST1		(0x0 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST2		(0x1 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST4		(0x2 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST8		(0x3 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST16		(0x4 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST32		(0x5 << 4)
> +#define REQ_CTRL_OPCODE_LD_ST64		(0x6 << 4)
> +#define REQ_CTRL_HOLDOFF_MASK		GENMASK(2, 0)
> +#define REQ_CTRL_HOLDOFF(n)		((n) & REQ_CTRL_HOLDOFF_MASK)

Everything here is FDMA_ so why not these as well

-- 
~Vinod

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

* Re: [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
@ 2016-06-06  4:54     ` Vinod Koul
  0 siblings, 0 replies; 113+ messages in thread
From: Vinod Koul @ 2016-06-06  4:54 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, ohad, bjorn.andersson, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc,
	Ludovic Barre

On Wed, May 25, 2016 at 05:06:40PM +0100, Peter Griffin wrote:

> @@ -527,6 +527,18 @@ config ZX_DMA
>  	help
>  	  Support the DMA engine for ZTE ZX296702 platform devices.
>  
> +config ST_FDMA
> +	tristate "ST FDMA dmaengine support"
> +	depends on ARCH_STI || COMPILE_TEST
> +        depends on ST_XP70_REMOTEPROC
> +	select DMA_ENGINE
> +	select DMA_VIRTUAL_CHANNELS
> +	help
> +	  Enable support for ST FDMA controller.
> +	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
> +
> +	  Say Y here if you have such a chipset.
> +	  If unsure, say N.

Alphabetical order in Kconfig and makefile please...

> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +#include <linux/platform_device.h>
> +#include <linux/interrupt.h>
> +#include <linux/clk.h>
> +#include <linux/dmaengine.h>
> +#include <linux/dmapool.h>
> +#include <linux/firmware.h>
> +#include <linux/elf.h>
> +#include <linux/atomic.h>
> +#include <linux/remoteproc.h>
> +#include <linux/io.h>

that seems to be quite a lot of headers, am sure some of them are not
required..


> +static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
> +{
> +	struct st_fdma_dev *fdev = fchan->fdev;
> +	u32 req_line_cfg = fchan->cfg.req_line;
> +	u32 dreq_line;
> +	int try = 0;
> +
> +	/*
> +	 * dreq_mask is shared for n channels of fdma, so all accesses must be
> +	 * atomic. if the dreq_mask it change between ffz ant set_bit,

s/ant/and

> +	switch (ch_sta) {
> +	case FDMA_CH_CMD_STA_PAUSED:
> +		fchan->status = DMA_PAUSED;
> +		break;

empty line here please

> +static void st_fdma_free_chan_res(struct dma_chan *chan)
> +{
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	unsigned long flags;
> +
> +	LIST_HEAD(head);
> +
> +	dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
> +		__func__, fchan->vchan.chan.chan_id);
> +
> +	if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
> +		st_fdma_dreq_put(fchan);
> +
> +	spin_lock_irqsave(&fchan->vchan.lock, flags);
> +	fchan->fdesc = NULL;
> +	vchan_get_all_descriptors(&fchan->vchan, &head);

and what are you doing with all these descriptors?

> +	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
> +
> +	dma_pool_destroy(fchan->node_pool);
> +	fchan->node_pool = NULL;
> +	memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
> +
> +	rproc_shutdown(fchan->fdev->rproc);
> +}

> +static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
> +					 dma_cookie_t cookie,
> +					 struct dma_tx_state *txstate)
> +{
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	struct virt_dma_desc *vd;
> +	enum dma_status ret;
> +	unsigned long flags;
> +
> +	ret = dma_cookie_status(chan, cookie, txstate);
> +	if (ret == DMA_COMPLETE)

check for txtstate here, that can be NULL and in that case no need to
calculate residue

> +
> +	dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);

why slave, you only support cyclic

> +	dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
> +	dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);


helps to print the 'ret' too

-- 
~Vinod

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

* Re: [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
@ 2016-06-06  4:54     ` Vinod Koul
  0 siblings, 0 replies; 113+ messages in thread
From: Vinod Koul @ 2016-06-06  4:54 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
	ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA, Ludovic Barre

On Wed, May 25, 2016 at 05:06:40PM +0100, Peter Griffin wrote:

> @@ -527,6 +527,18 @@ config ZX_DMA
>  	help
>  	  Support the DMA engine for ZTE ZX296702 platform devices.
>  
> +config ST_FDMA
> +	tristate "ST FDMA dmaengine support"
> +	depends on ARCH_STI || COMPILE_TEST
> +        depends on ST_XP70_REMOTEPROC
> +	select DMA_ENGINE
> +	select DMA_VIRTUAL_CHANNELS
> +	help
> +	  Enable support for ST FDMA controller.
> +	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
> +
> +	  Say Y here if you have such a chipset.
> +	  If unsure, say N.

Alphabetical order in Kconfig and makefile please...

> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +#include <linux/platform_device.h>
> +#include <linux/interrupt.h>
> +#include <linux/clk.h>
> +#include <linux/dmaengine.h>
> +#include <linux/dmapool.h>
> +#include <linux/firmware.h>
> +#include <linux/elf.h>
> +#include <linux/atomic.h>
> +#include <linux/remoteproc.h>
> +#include <linux/io.h>

that seems to be quite a lot of headers, am sure some of them are not
required..


> +static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
> +{
> +	struct st_fdma_dev *fdev = fchan->fdev;
> +	u32 req_line_cfg = fchan->cfg.req_line;
> +	u32 dreq_line;
> +	int try = 0;
> +
> +	/*
> +	 * dreq_mask is shared for n channels of fdma, so all accesses must be
> +	 * atomic. if the dreq_mask it change between ffz ant set_bit,

s/ant/and

> +	switch (ch_sta) {
> +	case FDMA_CH_CMD_STA_PAUSED:
> +		fchan->status = DMA_PAUSED;
> +		break;

empty line here please

> +static void st_fdma_free_chan_res(struct dma_chan *chan)
> +{
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	unsigned long flags;
> +
> +	LIST_HEAD(head);
> +
> +	dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
> +		__func__, fchan->vchan.chan.chan_id);
> +
> +	if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
> +		st_fdma_dreq_put(fchan);
> +
> +	spin_lock_irqsave(&fchan->vchan.lock, flags);
> +	fchan->fdesc = NULL;
> +	vchan_get_all_descriptors(&fchan->vchan, &head);

and what are you doing with all these descriptors?

> +	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
> +
> +	dma_pool_destroy(fchan->node_pool);
> +	fchan->node_pool = NULL;
> +	memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
> +
> +	rproc_shutdown(fchan->fdev->rproc);
> +}

> +static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
> +					 dma_cookie_t cookie,
> +					 struct dma_tx_state *txstate)
> +{
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	struct virt_dma_desc *vd;
> +	enum dma_status ret;
> +	unsigned long flags;
> +
> +	ret = dma_cookie_status(chan, cookie, txstate);
> +	if (ret == DMA_COMPLETE)

check for txtstate here, that can be NULL and in that case no need to
calculate residue

> +
> +	dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);

why slave, you only support cyclic

> +	dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
> +	dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);


helps to print the 'ret' too

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
@ 2016-06-06  4:54     ` Vinod Koul
  0 siblings, 0 replies; 113+ messages in thread
From: Vinod Koul @ 2016-06-06  4:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 25, 2016 at 05:06:40PM +0100, Peter Griffin wrote:

> @@ -527,6 +527,18 @@ config ZX_DMA
>  	help
>  	  Support the DMA engine for ZTE ZX296702 platform devices.
>  
> +config ST_FDMA
> +	tristate "ST FDMA dmaengine support"
> +	depends on ARCH_STI || COMPILE_TEST
> +        depends on ST_XP70_REMOTEPROC
> +	select DMA_ENGINE
> +	select DMA_VIRTUAL_CHANNELS
> +	help
> +	  Enable support for ST FDMA controller.
> +	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
> +
> +	  Say Y here if you have such a chipset.
> +	  If unsure, say N.

Alphabetical order in Kconfig and makefile please...

> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +#include <linux/platform_device.h>
> +#include <linux/interrupt.h>
> +#include <linux/clk.h>
> +#include <linux/dmaengine.h>
> +#include <linux/dmapool.h>
> +#include <linux/firmware.h>
> +#include <linux/elf.h>
> +#include <linux/atomic.h>
> +#include <linux/remoteproc.h>
> +#include <linux/io.h>

that seems to be quite a lot of headers, am sure some of them are not
required..


> +static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
> +{
> +	struct st_fdma_dev *fdev = fchan->fdev;
> +	u32 req_line_cfg = fchan->cfg.req_line;
> +	u32 dreq_line;
> +	int try = 0;
> +
> +	/*
> +	 * dreq_mask is shared for n channels of fdma, so all accesses must be
> +	 * atomic. if the dreq_mask it change between ffz ant set_bit,

s/ant/and

> +	switch (ch_sta) {
> +	case FDMA_CH_CMD_STA_PAUSED:
> +		fchan->status = DMA_PAUSED;
> +		break;

empty line here please

> +static void st_fdma_free_chan_res(struct dma_chan *chan)
> +{
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	unsigned long flags;
> +
> +	LIST_HEAD(head);
> +
> +	dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
> +		__func__, fchan->vchan.chan.chan_id);
> +
> +	if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
> +		st_fdma_dreq_put(fchan);
> +
> +	spin_lock_irqsave(&fchan->vchan.lock, flags);
> +	fchan->fdesc = NULL;
> +	vchan_get_all_descriptors(&fchan->vchan, &head);

and what are you doing with all these descriptors?

> +	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
> +
> +	dma_pool_destroy(fchan->node_pool);
> +	fchan->node_pool = NULL;
> +	memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
> +
> +	rproc_shutdown(fchan->fdev->rproc);
> +}

> +static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
> +					 dma_cookie_t cookie,
> +					 struct dma_tx_state *txstate)
> +{
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	struct virt_dma_desc *vd;
> +	enum dma_status ret;
> +	unsigned long flags;
> +
> +	ret = dma_cookie_status(chan, cookie, txstate);
> +	if (ret == DMA_COMPLETE)

check for txtstate here, that can be NULL and in that case no need to
calculate residue

> +
> +	dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);

why slave, you only support cyclic

> +	dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
> +	dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);


helps to print the 'ret' too

-- 
~Vinod

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

* Re: [PATCH 00/18]  Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
@ 2016-06-06  5:01   ` Vinod Koul
  0 siblings, 0 replies; 113+ messages in thread
From: Vinod Koul @ 2016-06-06  5:01 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, ohad, bjorn.andersson, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc

On Wed, May 25, 2016 at 05:06:33PM +0100, Peter Griffin wrote:
> 
> Peter Griffin (18):
>   dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
>     documentation
>   dmaengine: st_fdma:  Add STMicroelectronics FDMA driver header file
>   dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
>   dmaengine: st_fdma: Add xp70 firmware loading mechanism.
>   dmaengine: st_fdma: Add fdma suspend and resume callbacks.

I do not see the latter two patches in this series. Something is missed here
from cover to actual patches which is bit bizarre as one tends to generate
patches and cover together

>   ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
>   MAINTAINERS: Add FDMA driver files to STi section.
>   ARM: multi_v7_defconfig: Enable STi FDMA driver
>   ASoC: sti: Update DT example to match the driver code
>   ASoC: sti: Update example to include assigned-clocks and mclk-fs
>   ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
>   ARM: DT: STiH407: Add i2s_out pinctrl configuration
>   ARM: DT: STiH407: Add i2s_in pinctrl configuration
>   ARM: DT: STiH407: Add spdif_out pinctrl config
>   ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
>   ARM: STi: DT: STiH407: Add uniperif player dt nodes
>   ARM: STi: DT: STiH407: Add uniperif reader dt nodes
>   ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
> 
>  Documentation/devicetree/bindings/dma/st_fdma.txt  |   87 ++
>  .../devicetree/bindings/sound/st,sti-asoc-card.txt |   22 +-
>  MAINTAINERS                                        |    1 +
>  arch/arm/boot/dts/stih407-family.dtsi              |  164 +++
>  arch/arm/boot/dts/stih407-pinctrl.dtsi             |   55 +
>  arch/arm/boot/dts/stihxxx-b2120.dtsi               |   40 +
>  arch/arm/configs/multi_v7_defconfig                |    4 +
>  drivers/dma/Kconfig                                |   12 +
>  drivers/dma/Makefile                               |    1 +
>  drivers/dma/st_fdma.c                              | 1203 ++++++++++++++++++++
>  drivers/dma/st_fdma.h                              |  281 +++++
>  11 files changed, 1863 insertions(+), 7 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
>  create mode 100644 drivers/dma/st_fdma.c
>  create mode 100644 drivers/dma/st_fdma.h

-- 
~Vinod

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

* Re: [PATCH 00/18]  Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
@ 2016-06-06  5:01   ` Vinod Koul
  0 siblings, 0 replies; 113+ messages in thread
From: Vinod Koul @ 2016-06-06  5:01 UTC (permalink / raw)
  To: Peter Griffin
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
	maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
	ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A, arnd-r2nGTMty4D4,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-remoteproc-u79uwXL29TY76Z2rM5mHXA

On Wed, May 25, 2016 at 05:06:33PM +0100, Peter Griffin wrote:
> 
> Peter Griffin (18):
>   dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
>     documentation
>   dmaengine: st_fdma:  Add STMicroelectronics FDMA driver header file
>   dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
>   dmaengine: st_fdma: Add xp70 firmware loading mechanism.
>   dmaengine: st_fdma: Add fdma suspend and resume callbacks.

I do not see the latter two patches in this series. Something is missed here
from cover to actual patches which is bit bizarre as one tends to generate
patches and cover together

>   ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
>   MAINTAINERS: Add FDMA driver files to STi section.
>   ARM: multi_v7_defconfig: Enable STi FDMA driver
>   ASoC: sti: Update DT example to match the driver code
>   ASoC: sti: Update example to include assigned-clocks and mclk-fs
>   ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
>   ARM: DT: STiH407: Add i2s_out pinctrl configuration
>   ARM: DT: STiH407: Add i2s_in pinctrl configuration
>   ARM: DT: STiH407: Add spdif_out pinctrl config
>   ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
>   ARM: STi: DT: STiH407: Add uniperif player dt nodes
>   ARM: STi: DT: STiH407: Add uniperif reader dt nodes
>   ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
> 
>  Documentation/devicetree/bindings/dma/st_fdma.txt  |   87 ++
>  .../devicetree/bindings/sound/st,sti-asoc-card.txt |   22 +-
>  MAINTAINERS                                        |    1 +
>  arch/arm/boot/dts/stih407-family.dtsi              |  164 +++
>  arch/arm/boot/dts/stih407-pinctrl.dtsi             |   55 +
>  arch/arm/boot/dts/stihxxx-b2120.dtsi               |   40 +
>  arch/arm/configs/multi_v7_defconfig                |    4 +
>  drivers/dma/Kconfig                                |   12 +
>  drivers/dma/Makefile                               |    1 +
>  drivers/dma/st_fdma.c                              | 1203 ++++++++++++++++++++
>  drivers/dma/st_fdma.h                              |  281 +++++
>  11 files changed, 1863 insertions(+), 7 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
>  create mode 100644 drivers/dma/st_fdma.c
>  create mode 100644 drivers/dma/st_fdma.h

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 00/18]  Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
@ 2016-06-06  5:01   ` Vinod Koul
  0 siblings, 0 replies; 113+ messages in thread
From: Vinod Koul @ 2016-06-06  5:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 25, 2016 at 05:06:33PM +0100, Peter Griffin wrote:
> 
> Peter Griffin (18):
>   dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
>     documentation
>   dmaengine: st_fdma:  Add STMicroelectronics FDMA driver header file
>   dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
>   dmaengine: st_fdma: Add xp70 firmware loading mechanism.
>   dmaengine: st_fdma: Add fdma suspend and resume callbacks.

I do not see the latter two patches in this series. Something is missed here
from cover to actual patches which is bit bizarre as one tends to generate
patches and cover together

>   ARM: STi: DT: STiH407: Add FDMA driver dt nodes.
>   MAINTAINERS: Add FDMA driver files to STi section.
>   ARM: multi_v7_defconfig: Enable STi FDMA driver
>   ASoC: sti: Update DT example to match the driver code
>   ASoC: sti: Update example to include assigned-clocks and mclk-fs
>   ARM: multi_v7_defconfig: Enable STi and simple-card drivers.
>   ARM: DT: STiH407: Add i2s_out pinctrl configuration
>   ARM: DT: STiH407: Add i2s_in pinctrl configuration
>   ARM: DT: STiH407: Add spdif_out pinctrl config
>   ARM: STi: DT: STiH407: Add sti-sasg-codec dt node
>   ARM: STi: DT: STiH407: Add uniperif player dt nodes
>   ARM: STi: DT: STiH407: Add uniperif reader dt nodes
>   ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card
> 
>  Documentation/devicetree/bindings/dma/st_fdma.txt  |   87 ++
>  .../devicetree/bindings/sound/st,sti-asoc-card.txt |   22 +-
>  MAINTAINERS                                        |    1 +
>  arch/arm/boot/dts/stih407-family.dtsi              |  164 +++
>  arch/arm/boot/dts/stih407-pinctrl.dtsi             |   55 +
>  arch/arm/boot/dts/stihxxx-b2120.dtsi               |   40 +
>  arch/arm/configs/multi_v7_defconfig                |    4 +
>  drivers/dma/Kconfig                                |   12 +
>  drivers/dma/Makefile                               |    1 +
>  drivers/dma/st_fdma.c                              | 1203 ++++++++++++++++++++
>  drivers/dma/st_fdma.h                              |  281 +++++
>  11 files changed, 1863 insertions(+), 7 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
>  create mode 100644 drivers/dma/st_fdma.c
>  create mode 100644 drivers/dma/st_fdma.h

-- 
~Vinod

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

* Re: [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
  2016-05-25 17:10     ` Bjorn Andersson
@ 2016-06-06  7:22       ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-06  7:22 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, vinod.koul, ohad, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc

Hi Bjorn,

Thanks for reviewing.

On Wed, 25 May 2016, Bjorn Andersson wrote:

> On Wed 25 May 09:06 PDT 2016, Peter Griffin wrote:
> 
> > XP70 slim core is used as a basis for many IPs in the STi
> > chipsets such as fdma, display, and demux. To avoid
> > duplicating the elf loading code in each device driver
> > an xp70 rproc driver has been created.
> > 
> I like this approach.
> 
> [..]
> 
> > diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> [..]
> >  
> > +config ST_XP70_REMOTEPROC
> > +	tristate "XP70 slim remoteproc support"
> 
> As this "driver" in itself doesn't do anything I don't think it makes
> sense to have it user selectable. Please make the "clients" select it
> instead.

Good point, will fix in v5.

> 
> > +	depends on ARCH_STI
> > +	select REMOTEPROC
> > +	help
> > +	  Say y here to support xp70 slim core.
> > +	  If unsure say N.
> > +
> >  endmenu
> > diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> [..]
> > +#include <linux/clk.h>
> > +#include <linux/elf.h>
> 
> You should be able to drop inclusion of elf.h now.

Will fix in v5.

> 
> [..]
> > +static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
> > +{
> > +	int clk, err = 0;
> 
> No need to initialize err.

Will fix in v5.

> 
> > +
> > +	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
> > +		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
> > +		if (IS_ERR(xp70_rproc->clks[clk])) {
> > +			err = PTR_ERR(xp70_rproc->clks[clk]);
> > +			if (err == -EPROBE_DEFER)
> > +				goto err_put_clks;
> > +			xp70_rproc->clks[clk] = NULL;
> > +			break;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +
> > +err_put_clks:
> > +	while (--clk >= 0)
> > +		clk_put(xp70_rproc->clks[clk]);
> > +
> > +	return err;
> > +}
> > +
> [..]
> > +/**
> > + * Remoteproc xp70 specific device handlers
> > + */
> > +static int xp70_rproc_start(struct rproc *rproc)
> > +{
> > +	struct device *dev = &rproc->dev;
> > +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> > +	unsigned long hw_id, hw_ver, fw_rev;
> > +	u32 val, ret = 0;
> 
> ret should be signed and there's no need to initialize it.

Will fix in v5.

> 
> > +
> > +	ret = xp70_clk_enable(xp70_rproc);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to enable clocks\n");
> > +		goto err_clk;
> > +	}
> [..]
> > +
> > +	dev_dbg(dev, "XP70 started\n");
> > +
> > +err_clk:
> > +	return ret;
> > +}
> > +
> > +static int xp70_rproc_stop(struct rproc *rproc)
> > +{
> > +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> > +	u32 val;
> > +
> > +	/* mask all (cmd & int) channels */
> > +	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> > +	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> > +
> > +	/* disable cpu pipeline clock */
> > +	writel_relaxed(XP70_CLK_GATE_DIS
> > +		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> > +
> > +	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
> 
> Don't you want to ensure ordering of these writes? Perhaps making this
> last one a writel()?

That is a good point. In the past these writes were all part of the same
mapping. But now it is split between several mappings
(slimcore, peri, dmem) ordering of the writes could be an issue.

Will change to writel / readl in v5.

> 
> > +
> > +	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
> > +	if (val & XP70_EN_RUN)
> > +		dev_warn(&rproc->dev, "Failed to disable XP70");
> > +
> > +	xp70_clk_disable(xp70_rproc);
> > +
> > +	dev_dbg(&rproc->dev, "xp70 stopped\n");
> > +
> > +	return 0;
> > +}
> > +
> > +static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
> > +{
> > +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> > +	void *va = NULL;
> > +	int i;
> > +
> > +	for (i = 0; i < XP70_MEM_MAX; i++) {
> > +
> > +		if (da != xp70_rproc->mem[i].bus_addr)
> > +			continue;
> > +
> > +		va = xp70_rproc->mem[i].cpu_addr;
> > +			break;
> > +	}
> 
> Please clean up the indentation and drop the extra newline at the
> beginning in this loop.

Will fix in v5

> 
> > +
> > +	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
> > +		, __func__, da, len, va);
> > +
> > +	return va;
> > +}
> > +
> > +static struct rproc_ops xp70_rproc_ops = {
> > +	.start		= xp70_rproc_start,
> > +	.stop		= xp70_rproc_stop,
> > +	.da_to_va       = xp70_rproc_da_to_va,
> > +};
> > +
> > +/**
> > + * Firmware handler operations: sanity, boot address, load ...
> > + */
> > +
> > +static struct resource_table empty_rsc_tbl = {
> > +	.ver = 1,
> > +	.num = 0,
> > +};
> 
> 
> I'm looking at making the resource table optional, good to see another
> vote for that. Looks good for now though.
> 
> [..]
> 
> > +
> > +/**
> > +  * xp70_rproc_alloc - allocate and initialise xp70 rproc
> 
> Drop one of the two spaces indenting this block and add () after then
> function name.

Will fix in v5

> 
> > +  * @pdev: Pointer to the platform_device struct
> > +  * @fw_name: Name of firmware for rproc to use
> > +  *
> > +  * Function for allocating and initialising a xp70 rproc for use by
> > +  * device drivers whose IP is based around the xp70 slim core. It
> > +  * obtains and enables any clocks required by the xp70 core and also
> > +  * ioremaps the various IO.
> > +  *
> > +  * Returns rproc pointer or PTR_ERR() on error.
> > +  */
> > +
> > +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct st_xp70_rproc *xp70_rproc;
> > +	struct device_node *np = dev->of_node;
> > +	struct rproc *rproc;
> > +	struct resource *res;
> > +	int err, i;
> > +	const struct rproc_fw_ops *elf_ops;
> > +
> > +	if (!np || !fw_name)
> > +		return ERR_PTR(-EINVAL);
> 
> This should, I believe, only ever happen in development. So if you want
> to keep it to aid developers feel free to throw in a WARN_ON() in the
> condition.

Will add WARN_ON in v5.

> 
> > +
> > +	if (!of_device_is_compatible(np, "st,xp70-rproc"))
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
> > +			fw_name, sizeof(*xp70_rproc));
> > +	if (!rproc)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	rproc->has_iommu = false;
> > +
> > +	xp70_rproc = rproc->priv;
> > +	xp70_rproc->rproc = rproc;
> > +
> > +	/* Get standard ELF ops */
> > +	elf_ops = rproc_get_elf_ops();
> > +
> > +	/* Use some generic elf ops */
> > +	xp70_rproc_fw_ops.load = elf_ops->load;
> > +	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
> > +
> > +	rproc->fw_ops = &xp70_rproc_fw_ops;
> > +
> > +	/* get imem and dmem */
> > +	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
> > +		res = xp70_rproc->mem[i].io_res;
> > +
> 
> io_res is NULL here, and res is directly assigned again. So drop this
> and io_res from the struct.

Good point. Will fix in v5.

> 
> > +		res = platform_get_resource_byname
> > +			(pdev, IORESOURCE_MEM, mem_names[i]);
> > +
> > +		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
> > +		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
> > +			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
> > +			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
> > +			goto err;
> > +		}
> > +		xp70_rproc->mem[i].bus_addr = res->start;
> > +		xp70_rproc->mem[i].size = resource_size(res);
> > +	}
> > +
> > +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
> > +
> > +	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
> > +	if (IS_ERR(xp70_rproc->slimcore)) {
> > +		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
> > +		err = PTR_ERR(xp70_rproc->slimcore);
> > +		goto err;
> > +	}
> > +
> > +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
> > +
> > +	xp70_rproc->peri = devm_ioremap_resource(dev, res);
> > +	if (IS_ERR(xp70_rproc->peri)) {
> > +		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
> > +		err = PTR_ERR(xp70_rproc->peri);
> > +		goto err;
> > +	}
> > +
> > +	err = xp70_clk_get(xp70_rproc, dev);
> > +	if (err)
> > +		goto err;
> > +
> > +	/* Register as a remoteproc device */
> > +	err = rproc_add(rproc);
> > +	if (err) {
> > +		dev_err(dev, "registration of xp70 remoteproc failed\n");
> > +		goto err;
> 
> In this case you should also put the clocks.

Will fix in v5.

> 
> > +	}
> > +
> > +	dev_dbg(dev, "XP70 rproc init successful\n");
> > +	return rproc;
> > +
> > +err:
> > +	rproc_put(rproc);
> > +	return ERR_PTR(err);
> > +}
> > +EXPORT_SYMBOL(xp70_rproc_alloc);
> > +
> > +/**
> > +  * xp70_rproc_put - put xp70 rproc resources
> > +  * @xp70_rproc: Pointer to the st_xp70_rproc struct
> > +  *
> > +  * Function for calling respective _put() functions on
> > +  * xp70_rproc resources.
> > +  *
> > +  * Returns rproc pointer or PTR_ERR() on error.
> > +  */
> > +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
> > +{
> > +	int clk;
> > +
> > +	if (!xp70_rproc)
> > +		return;
> > +
> > +	rproc_put(xp70_rproc->rproc);
> > +
> > +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> > +		clk_put(xp70_rproc->clks[clk]);
> 
> rproc_put() will free your private data, i.e. xp70_rproc, so you must
> put your clocks before that.

Good spot. Will fix in v5.

> 
> > +
> > +}
> > +EXPORT_SYMBOL(xp70_rproc_put);
> > +
> > +MODULE_AUTHOR("Peter Griffin");
> > +MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
> [..]
> > +
> > +#define XP70_MEM_MAX 2
> > +#define XP70_MAX_CLK 4
> > +#define NAME_SZ 10
> 
> NAME_SZ seems unused and would be too generic.

Will fix in v5.

> 
> > +
> > +enum {
> > +	DMEM,
> > +	IMEM,
> 
> These are too generic for a header file.

Changed to XP70_DMEM in v5.

> 
> > +};
> > +
> > +/**
> > + * struct xp70_mem - xp70 internal memory structure
> > + * @cpu_addr: MPU virtual address of the memory region
> > + * @bus_addr: Bus address used to access the memory region
> > + * @dev_addr: Device address from Wakeup M3 view
> > + * @size: Size of the memory region
> > + */
> > +struct xp70_mem {
> > +	void __iomem *cpu_addr;
> > +	phys_addr_t bus_addr;
> > +	u32 dev_addr;
> 
> dev_addr is unused.

Will fix in v5.


> 
> > +	size_t size;
> > +	struct resource *io_res;
> 
> io_res is unused.

Will fix in v5.

> 
> > +};
> > +
> > +/**
> > + * struct st_xp70_rproc - XP70 slim core
> > + * @rproc: rproc handle
> > + * @pdev: pointer to platform device
> > + * @mem: xp70 memory information
> > + * @slimcore: xp70 slimcore regs
> > + * @peri: xp70 peripheral regs
> > + * @clks: xp70 clocks
> > + */
> > +struct st_xp70_rproc {
> > +	struct rproc *rproc;
> > +	struct platform_device *pdev;
> 
> pdev is unused.

Will fix in v5.

> 
> > +	struct xp70_mem mem[XP70_MEM_MAX];
> > +	void __iomem *slimcore;
> > +	void __iomem *peri;
> > +	struct clk *clks[XP70_MAX_CLK];
> > +};
> 
> I generally don't like sharing a struct like this between two
> implementations, but I don't think it's worth working around it in this
> case.
> 
> Perhaps you can group the members into a section of "public" and a
> section of "private" members; with a /* st_xp70_rproc private */ heading
> the latter?

Heading added in v5.

> 
> > +
> > +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
> 
> For consistency I think xp70_rproc_alloc() should return a st_xp70_rproc
> reference, rather than forcing the clients pull that pointer out of
> rproc->priv.

Good idea, have changed like you suggest in v5.

> 
> > +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> > +
> > +#endif

Regards,

Peter.

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

* [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver
@ 2016-06-06  7:22       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-06  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bjorn,

Thanks for reviewing.

On Wed, 25 May 2016, Bjorn Andersson wrote:

> On Wed 25 May 09:06 PDT 2016, Peter Griffin wrote:
> 
> > XP70 slim core is used as a basis for many IPs in the STi
> > chipsets such as fdma, display, and demux. To avoid
> > duplicating the elf loading code in each device driver
> > an xp70 rproc driver has been created.
> > 
> I like this approach.
> 
> [..]
> 
> > diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> [..]
> >  
> > +config ST_XP70_REMOTEPROC
> > +	tristate "XP70 slim remoteproc support"
> 
> As this "driver" in itself doesn't do anything I don't think it makes
> sense to have it user selectable. Please make the "clients" select it
> instead.

Good point, will fix in v5.

> 
> > +	depends on ARCH_STI
> > +	select REMOTEPROC
> > +	help
> > +	  Say y here to support xp70 slim core.
> > +	  If unsure say N.
> > +
> >  endmenu
> > diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> [..]
> > +#include <linux/clk.h>
> > +#include <linux/elf.h>
> 
> You should be able to drop inclusion of elf.h now.

Will fix in v5.

> 
> [..]
> > +static int xp70_clk_get(struct st_xp70_rproc *xp70_rproc, struct device *dev)
> > +{
> > +	int clk, err = 0;
> 
> No need to initialize err.

Will fix in v5.

> 
> > +
> > +	for (clk = 0; clk < XP70_MAX_CLK; clk++) {
> > +		xp70_rproc->clks[clk] = of_clk_get(dev->of_node, clk);
> > +		if (IS_ERR(xp70_rproc->clks[clk])) {
> > +			err = PTR_ERR(xp70_rproc->clks[clk]);
> > +			if (err == -EPROBE_DEFER)
> > +				goto err_put_clks;
> > +			xp70_rproc->clks[clk] = NULL;
> > +			break;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +
> > +err_put_clks:
> > +	while (--clk >= 0)
> > +		clk_put(xp70_rproc->clks[clk]);
> > +
> > +	return err;
> > +}
> > +
> [..]
> > +/**
> > + * Remoteproc xp70 specific device handlers
> > + */
> > +static int xp70_rproc_start(struct rproc *rproc)
> > +{
> > +	struct device *dev = &rproc->dev;
> > +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> > +	unsigned long hw_id, hw_ver, fw_rev;
> > +	u32 val, ret = 0;
> 
> ret should be signed and there's no need to initialize it.

Will fix in v5.

> 
> > +
> > +	ret = xp70_clk_enable(xp70_rproc);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to enable clocks\n");
> > +		goto err_clk;
> > +	}
> [..]
> > +
> > +	dev_dbg(dev, "XP70 started\n");
> > +
> > +err_clk:
> > +	return ret;
> > +}
> > +
> > +static int xp70_rproc_stop(struct rproc *rproc)
> > +{
> > +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> > +	u32 val;
> > +
> > +	/* mask all (cmd & int) channels */
> > +	writel_relaxed(0UL, xp70_rproc->peri + XP70_INT_MASK_OFST);
> > +	writel_relaxed(0UL, xp70_rproc->peri + XP70_CMD_MASK_OFST);
> > +
> > +	/* disable cpu pipeline clock */
> > +	writel_relaxed(XP70_CLK_GATE_DIS
> > +		, xp70_rproc->slimcore + XP70_CLK_GATE_OFST);
> > +
> > +	writel_relaxed(!XP70_EN_RUN, xp70_rproc->slimcore + XP70_EN_OFST);
> 
> Don't you want to ensure ordering of these writes? Perhaps making this
> last one a writel()?

That is a good point. In the past these writes were all part of the same
mapping. But now it is split between several mappings
(slimcore, peri, dmem) ordering of the writes could be an issue.

Will change to writel / readl in v5.

> 
> > +
> > +	val = readl_relaxed(xp70_rproc->slimcore + XP70_EN_OFST);
> > +	if (val & XP70_EN_RUN)
> > +		dev_warn(&rproc->dev, "Failed to disable XP70");
> > +
> > +	xp70_clk_disable(xp70_rproc);
> > +
> > +	dev_dbg(&rproc->dev, "xp70 stopped\n");
> > +
> > +	return 0;
> > +}
> > +
> > +static void *xp70_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
> > +{
> > +	struct st_xp70_rproc *xp70_rproc = rproc->priv;
> > +	void *va = NULL;
> > +	int i;
> > +
> > +	for (i = 0; i < XP70_MEM_MAX; i++) {
> > +
> > +		if (da != xp70_rproc->mem[i].bus_addr)
> > +			continue;
> > +
> > +		va = xp70_rproc->mem[i].cpu_addr;
> > +			break;
> > +	}
> 
> Please clean up the indentation and drop the extra newline at the
> beginning in this loop.

Will fix in v5

> 
> > +
> > +	dev_dbg(&rproc->dev, "%s: da = 0x%llx len = 0x%x va = 0x%p\n"
> > +		, __func__, da, len, va);
> > +
> > +	return va;
> > +}
> > +
> > +static struct rproc_ops xp70_rproc_ops = {
> > +	.start		= xp70_rproc_start,
> > +	.stop		= xp70_rproc_stop,
> > +	.da_to_va       = xp70_rproc_da_to_va,
> > +};
> > +
> > +/**
> > + * Firmware handler operations: sanity, boot address, load ...
> > + */
> > +
> > +static struct resource_table empty_rsc_tbl = {
> > +	.ver = 1,
> > +	.num = 0,
> > +};
> 
> 
> I'm looking at making the resource table optional, good to see another
> vote for that. Looks good for now though.
> 
> [..]
> 
> > +
> > +/**
> > +  * xp70_rproc_alloc - allocate and initialise xp70 rproc
> 
> Drop one of the two spaces indenting this block and add () after then
> function name.

Will fix in v5

> 
> > +  * @pdev: Pointer to the platform_device struct
> > +  * @fw_name: Name of firmware for rproc to use
> > +  *
> > +  * Function for allocating and initialising a xp70 rproc for use by
> > +  * device drivers whose IP is based around the xp70 slim core. It
> > +  * obtains and enables any clocks required by the xp70 core and also
> > +  * ioremaps the various IO.
> > +  *
> > +  * Returns rproc pointer or PTR_ERR() on error.
> > +  */
> > +
> > +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct st_xp70_rproc *xp70_rproc;
> > +	struct device_node *np = dev->of_node;
> > +	struct rproc *rproc;
> > +	struct resource *res;
> > +	int err, i;
> > +	const struct rproc_fw_ops *elf_ops;
> > +
> > +	if (!np || !fw_name)
> > +		return ERR_PTR(-EINVAL);
> 
> This should, I believe, only ever happen in development. So if you want
> to keep it to aid developers feel free to throw in a WARN_ON() in the
> condition.

Will add WARN_ON in v5.

> 
> > +
> > +	if (!of_device_is_compatible(np, "st,xp70-rproc"))
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	rproc = rproc_alloc(dev, np->name, &xp70_rproc_ops,
> > +			fw_name, sizeof(*xp70_rproc));
> > +	if (!rproc)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	rproc->has_iommu = false;
> > +
> > +	xp70_rproc = rproc->priv;
> > +	xp70_rproc->rproc = rproc;
> > +
> > +	/* Get standard ELF ops */
> > +	elf_ops = rproc_get_elf_ops();
> > +
> > +	/* Use some generic elf ops */
> > +	xp70_rproc_fw_ops.load = elf_ops->load;
> > +	xp70_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
> > +
> > +	rproc->fw_ops = &xp70_rproc_fw_ops;
> > +
> > +	/* get imem and dmem */
> > +	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
> > +		res = xp70_rproc->mem[i].io_res;
> > +
> 
> io_res is NULL here, and res is directly assigned again. So drop this
> and io_res from the struct.

Good point. Will fix in v5.

> 
> > +		res = platform_get_resource_byname
> > +			(pdev, IORESOURCE_MEM, mem_names[i]);
> > +
> > +		xp70_rproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
> > +		if (IS_ERR(xp70_rproc->mem[i].cpu_addr)) {
> > +			dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
> > +			err = PTR_ERR(xp70_rproc->mem[i].cpu_addr);
> > +			goto err;
> > +		}
> > +		xp70_rproc->mem[i].bus_addr = res->start;
> > +		xp70_rproc->mem[i].size = resource_size(res);
> > +	}
> > +
> > +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
> > +
> > +	xp70_rproc->slimcore = devm_ioremap_resource(dev, res);
> > +	if (IS_ERR(xp70_rproc->slimcore)) {
> > +		dev_err(&pdev->dev, "devm_ioremap_resource failed for slimcore\n");
> > +		err = PTR_ERR(xp70_rproc->slimcore);
> > +		goto err;
> > +	}
> > +
> > +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
> > +
> > +	xp70_rproc->peri = devm_ioremap_resource(dev, res);
> > +	if (IS_ERR(xp70_rproc->peri)) {
> > +		dev_err(&pdev->dev, "devm_ioremap_resource failed for peri\n");
> > +		err = PTR_ERR(xp70_rproc->peri);
> > +		goto err;
> > +	}
> > +
> > +	err = xp70_clk_get(xp70_rproc, dev);
> > +	if (err)
> > +		goto err;
> > +
> > +	/* Register as a remoteproc device */
> > +	err = rproc_add(rproc);
> > +	if (err) {
> > +		dev_err(dev, "registration of xp70 remoteproc failed\n");
> > +		goto err;
> 
> In this case you should also put the clocks.

Will fix in v5.

> 
> > +	}
> > +
> > +	dev_dbg(dev, "XP70 rproc init successful\n");
> > +	return rproc;
> > +
> > +err:
> > +	rproc_put(rproc);
> > +	return ERR_PTR(err);
> > +}
> > +EXPORT_SYMBOL(xp70_rproc_alloc);
> > +
> > +/**
> > +  * xp70_rproc_put - put xp70 rproc resources
> > +  * @xp70_rproc: Pointer to the st_xp70_rproc struct
> > +  *
> > +  * Function for calling respective _put() functions on
> > +  * xp70_rproc resources.
> > +  *
> > +  * Returns rproc pointer or PTR_ERR() on error.
> > +  */
> > +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc)
> > +{
> > +	int clk;
> > +
> > +	if (!xp70_rproc)
> > +		return;
> > +
> > +	rproc_put(xp70_rproc->rproc);
> > +
> > +	for (clk = 0; clk < XP70_MAX_CLK && xp70_rproc->clks[clk]; clk++)
> > +		clk_put(xp70_rproc->clks[clk]);
> 
> rproc_put() will free your private data, i.e. xp70_rproc, so you must
> put your clocks before that.

Good spot. Will fix in v5.

> 
> > +
> > +}
> > +EXPORT_SYMBOL(xp70_rproc_put);
> > +
> > +MODULE_AUTHOR("Peter Griffin");
> > +MODULE_DESCRIPTION("STMicroelectronics XP70 rproc driver");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/remoteproc/st_xp70_rproc.h b/include/linux/remoteproc/st_xp70_rproc.h
> [..]
> > +
> > +#define XP70_MEM_MAX 2
> > +#define XP70_MAX_CLK 4
> > +#define NAME_SZ 10
> 
> NAME_SZ seems unused and would be too generic.

Will fix in v5.

> 
> > +
> > +enum {
> > +	DMEM,
> > +	IMEM,
> 
> These are too generic for a header file.

Changed to XP70_DMEM in v5.

> 
> > +};
> > +
> > +/**
> > + * struct xp70_mem - xp70 internal memory structure
> > + * @cpu_addr: MPU virtual address of the memory region
> > + * @bus_addr: Bus address used to access the memory region
> > + * @dev_addr: Device address from Wakeup M3 view
> > + * @size: Size of the memory region
> > + */
> > +struct xp70_mem {
> > +	void __iomem *cpu_addr;
> > +	phys_addr_t bus_addr;
> > +	u32 dev_addr;
> 
> dev_addr is unused.

Will fix in v5.


> 
> > +	size_t size;
> > +	struct resource *io_res;
> 
> io_res is unused.

Will fix in v5.

> 
> > +};
> > +
> > +/**
> > + * struct st_xp70_rproc - XP70 slim core
> > + * @rproc: rproc handle
> > + * @pdev: pointer to platform device
> > + * @mem: xp70 memory information
> > + * @slimcore: xp70 slimcore regs
> > + * @peri: xp70 peripheral regs
> > + * @clks: xp70 clocks
> > + */
> > +struct st_xp70_rproc {
> > +	struct rproc *rproc;
> > +	struct platform_device *pdev;
> 
> pdev is unused.

Will fix in v5.

> 
> > +	struct xp70_mem mem[XP70_MEM_MAX];
> > +	void __iomem *slimcore;
> > +	void __iomem *peri;
> > +	struct clk *clks[XP70_MAX_CLK];
> > +};
> 
> I generally don't like sharing a struct like this between two
> implementations, but I don't think it's worth working around it in this
> case.
> 
> Perhaps you can group the members into a section of "public" and a
> section of "private" members; with a /* st_xp70_rproc private */ heading
> the latter?

Heading added in v5.

> 
> > +
> > +struct rproc *xp70_rproc_alloc(struct platform_device *pdev, char *fw_name);
> 
> For consistency I think xp70_rproc_alloc() should return a st_xp70_rproc
> reference, rather than forcing the clients pull that pointer out of
> rproc->priv.

Good idea, have changed like you suggest in v5.

> 
> > +void xp70_rproc_put(struct st_xp70_rproc *xp70_rproc);
> > +
> > +#endif

Regards,

Peter.

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

* Re: [PATCH 00/18]  Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
  2016-06-06  5:01   ` Vinod Koul
@ 2016-06-06 15:09     ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-06 15:09 UTC (permalink / raw)
  To: Vinod Koul
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, ohad, bjorn.andersson, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc

Hi Vinod,

On Mon, 06 Jun 2016, Vinod Koul wrote:

> On Wed, May 25, 2016 at 05:06:33PM +0100, Peter Griffin wrote:
> > 
> > Peter Griffin (18):
> >   dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
> >     documentation
> >   dmaengine: st_fdma:  Add STMicroelectronics FDMA driver header file
> >   dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
> >   dmaengine: st_fdma: Add xp70 firmware loading mechanism.
> >   dmaengine: st_fdma: Add fdma suspend and resume callbacks.
> 
> I do not see the latter two patches in this series. Something is missed here
> from cover to actual patches which is bit bizarre as one tends to generate
> patches and cover together

Sorry I accidentally sent two cover letters as part of this series. The v4
one is here https://lkml.org/lkml/2016/5/25/451.

regards,

Peter.

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

* [PATCH 00/18]  Add support for FDMA DMA controller and xp70 rproc found on STi chipsets
@ 2016-06-06 15:09     ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-06 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vinod,

On Mon, 06 Jun 2016, Vinod Koul wrote:

> On Wed, May 25, 2016 at 05:06:33PM +0100, Peter Griffin wrote:
> > 
> > Peter Griffin (18):
> >   dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding
> >     documentation
> >   dmaengine: st_fdma:  Add STMicroelectronics FDMA driver header file
> >   dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
> >   dmaengine: st_fdma: Add xp70 firmware loading mechanism.
> >   dmaengine: st_fdma: Add fdma suspend and resume callbacks.
> 
> I do not see the latter two patches in this series. Something is missed here
> from cover to actual patches which is bit bizarre as one tends to generate
> patches and cover together

Sorry I accidentally sent two cover letters as part of this series. The v4
one is here https://lkml.org/lkml/2016/5/25/451.

regards,

Peter.

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

* Re: [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
  2016-06-06  4:54     ` Vinod Koul
@ 2016-06-06 17:38       ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-06 17:38 UTC (permalink / raw)
  To: Vinod Koul
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, ohad, bjorn.andersson, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc,
	Ludovic Barre

Hi Vinod,

Thanks for reviewing v4 series.

On Mon, 06 Jun 2016, Vinod Koul wrote:

> On Wed, May 25, 2016 at 05:06:40PM +0100, Peter Griffin wrote:
> 
> > @@ -527,6 +527,18 @@ config ZX_DMA
> >  	help
> >  	  Support the DMA engine for ZTE ZX296702 platform devices.
> >  
> > +config ST_FDMA
> > +	tristate "ST FDMA dmaengine support"
> > +	depends on ARCH_STI || COMPILE_TEST
> > +        depends on ST_XP70_REMOTEPROC
> > +	select DMA_ENGINE
> > +	select DMA_VIRTUAL_CHANNELS
> > +	help
> > +	  Enable support for ST FDMA controller.
> > +	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
> > +
> > +	  Say Y here if you have such a chipset.
> > +	  If unsure, say N.
> 
> Alphabetical order in Kconfig and makefile please...

OK, will fix in v5.

> 
> > +#include <linux/init.h>
> > +#include <linux/module.h>
> > +#include <linux/slab.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_dma.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/clk.h>
> > +#include <linux/dmaengine.h>
> > +#include <linux/dmapool.h>
> > +#include <linux/firmware.h>
> > +#include <linux/elf.h>
> > +#include <linux/atomic.h>
> > +#include <linux/remoteproc.h>
> > +#include <linux/io.h>
> 
> that seems to be quite a lot of headers, am sure some of them are not
> required..

Yes your right this hasn't kept aligned with the driver changes through the
various submissions. I will prune the headers in v5.

> 
> 
> > +static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
> > +{
> > +	struct st_fdma_dev *fdev = fchan->fdev;
> > +	u32 req_line_cfg = fchan->cfg.req_line;
> > +	u32 dreq_line;
> > +	int try = 0;
> > +
> > +	/*
> > +	 * dreq_mask is shared for n channels of fdma, so all accesses must be
> > +	 * atomic. if the dreq_mask it change between ffz ant set_bit,
> 
> s/ant/and

Will fix in v5.

> 
> > +	switch (ch_sta) {
> > +	case FDMA_CH_CMD_STA_PAUSED:
> > +		fchan->status = DMA_PAUSED;
> > +		break;
> 
> empty line here please

Fixed in v5.
> 
> > +static void st_fdma_free_chan_res(struct dma_chan *chan)
> > +{
> > +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> > +	unsigned long flags;
> > +
> > +	LIST_HEAD(head);
> > +
> > +	dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
> > +		__func__, fchan->vchan.chan.chan_id);
> > +
> > +	if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
> > +		st_fdma_dreq_put(fchan);
> > +
> > +	spin_lock_irqsave(&fchan->vchan.lock, flags);
> > +	fchan->fdesc = NULL;
> > +	vchan_get_all_descriptors(&fchan->vchan, &head);
> 
> and what are you doing with all these descriptors?

Looks like a copy/paste error from terminate_all(). Will fix in v5.

> 
> > +	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
> > +
> > +	dma_pool_destroy(fchan->node_pool);
> > +	fchan->node_pool = NULL;
> > +	memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
> > +
> > +	rproc_shutdown(fchan->fdev->rproc);
> > +}
> 
> > +static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
> > +					 dma_cookie_t cookie,
> > +					 struct dma_tx_state *txstate)
> > +{
> > +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> > +	struct virt_dma_desc *vd;
> > +	enum dma_status ret;
> > +	unsigned long flags;
> > +
> > +	ret = dma_cookie_status(chan, cookie, txstate);
> > +	if (ret == DMA_COMPLETE)
> 
> check for txtstate here, that can be NULL and in that case no need to
> calculate residue

Will fix in v5.

> 
> > +
> > +	dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);
> 
> why slave, you only support cyclic

No, we also support device_prep_slave_sg().

> 
> > +	dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
> > +	dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);
> 
> 
> helps to print the 'ret' too

Will fix in v5.

regards,

Peter

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

* [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support
@ 2016-06-06 17:38       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-06 17:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vinod,

Thanks for reviewing v4 series.

On Mon, 06 Jun 2016, Vinod Koul wrote:

> On Wed, May 25, 2016 at 05:06:40PM +0100, Peter Griffin wrote:
> 
> > @@ -527,6 +527,18 @@ config ZX_DMA
> >  	help
> >  	  Support the DMA engine for ZTE ZX296702 platform devices.
> >  
> > +config ST_FDMA
> > +	tristate "ST FDMA dmaengine support"
> > +	depends on ARCH_STI || COMPILE_TEST
> > +        depends on ST_XP70_REMOTEPROC
> > +	select DMA_ENGINE
> > +	select DMA_VIRTUAL_CHANNELS
> > +	help
> > +	  Enable support for ST FDMA controller.
> > +	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
> > +
> > +	  Say Y here if you have such a chipset.
> > +	  If unsure, say N.
> 
> Alphabetical order in Kconfig and makefile please...

OK, will fix in v5.

> 
> > +#include <linux/init.h>
> > +#include <linux/module.h>
> > +#include <linux/slab.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_dma.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/clk.h>
> > +#include <linux/dmaengine.h>
> > +#include <linux/dmapool.h>
> > +#include <linux/firmware.h>
> > +#include <linux/elf.h>
> > +#include <linux/atomic.h>
> > +#include <linux/remoteproc.h>
> > +#include <linux/io.h>
> 
> that seems to be quite a lot of headers, am sure some of them are not
> required..

Yes your right this hasn't kept aligned with the driver changes through the
various submissions. I will prune the headers in v5.

> 
> 
> > +static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
> > +{
> > +	struct st_fdma_dev *fdev = fchan->fdev;
> > +	u32 req_line_cfg = fchan->cfg.req_line;
> > +	u32 dreq_line;
> > +	int try = 0;
> > +
> > +	/*
> > +	 * dreq_mask is shared for n channels of fdma, so all accesses must be
> > +	 * atomic. if the dreq_mask it change between ffz ant set_bit,
> 
> s/ant/and

Will fix in v5.

> 
> > +	switch (ch_sta) {
> > +	case FDMA_CH_CMD_STA_PAUSED:
> > +		fchan->status = DMA_PAUSED;
> > +		break;
> 
> empty line here please

Fixed in v5.
> 
> > +static void st_fdma_free_chan_res(struct dma_chan *chan)
> > +{
> > +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> > +	unsigned long flags;
> > +
> > +	LIST_HEAD(head);
> > +
> > +	dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
> > +		__func__, fchan->vchan.chan.chan_id);
> > +
> > +	if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
> > +		st_fdma_dreq_put(fchan);
> > +
> > +	spin_lock_irqsave(&fchan->vchan.lock, flags);
> > +	fchan->fdesc = NULL;
> > +	vchan_get_all_descriptors(&fchan->vchan, &head);
> 
> and what are you doing with all these descriptors?

Looks like a copy/paste error from terminate_all(). Will fix in v5.

> 
> > +	spin_unlock_irqrestore(&fchan->vchan.lock, flags);
> > +
> > +	dma_pool_destroy(fchan->node_pool);
> > +	fchan->node_pool = NULL;
> > +	memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
> > +
> > +	rproc_shutdown(fchan->fdev->rproc);
> > +}
> 
> > +static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
> > +					 dma_cookie_t cookie,
> > +					 struct dma_tx_state *txstate)
> > +{
> > +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> > +	struct virt_dma_desc *vd;
> > +	enum dma_status ret;
> > +	unsigned long flags;
> > +
> > +	ret = dma_cookie_status(chan, cookie, txstate);
> > +	if (ret == DMA_COMPLETE)
> 
> check for txtstate here, that can be NULL and in that case no need to
> calculate residue

Will fix in v5.

> 
> > +
> > +	dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);
> 
> why slave, you only support cyclic

No, we also support device_prep_slave_sg().

> 
> > +	dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
> > +	dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);
> 
> 
> helps to print the 'ret' too

Will fix in v5.

regards,

Peter

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

* Re: [PATCH v4 05/18] dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
  2016-06-06  4:36     ` Vinod Koul
@ 2016-06-06 17:40       ` Peter Griffin
  -1 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-06 17:40 UTC (permalink / raw)
  To: Vinod Koul
  Cc: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
	maxime.coquelin, patrice.chotard, ohad, bjorn.andersson, arnd,
	lee.jones, devicetree, dmaengine, linux-remoteproc,
	Ludovic Barre

Hi Vinod,

Thanks for reviewing.

On Mon, 06 Jun 2016, Vinod Koul wrote:

> On Wed, May 25, 2016 at 05:06:39PM +0100, Peter Griffin wrote:
> 
> > +/*
> > + * request control bits
> > + */
> > +#define REQ_CTRL_NUM_OPS_MASK		GENMASK(31, 24)
> > +#define REQ_CTRL_NUM_OPS(n)		(REQ_CTRL_NUM_OPS_MASK & ((n) << 24))
> > +#define REQ_CTRL_INITIATOR_MASK		BIT(22)
> > +#define	REQ_CTRL_INIT0			(0x0 << 22)
> > +#define	REQ_CTRL_INIT1			(0x1 << 22)
> 
> pls keep spaces or tabs, not both :(

Will fix in v5.

> 
> > +#define REQ_CTRL_INC_ADDR_ON		BIT(21)
> > +#define REQ_CTRL_DATA_SWAP_ON		BIT(17)
> > +#define REQ_CTRL_WNR			BIT(14)
> > +#define REQ_CTRL_OPCODE_MASK		GENMASK(7, 4)
> > +#define REQ_CTRL_OPCODE_LD_ST1		(0x0 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST2		(0x1 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST4		(0x2 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST8		(0x3 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST16		(0x4 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST32		(0x5 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST64		(0x6 << 4)
> > +#define REQ_CTRL_HOLDOFF_MASK		GENMASK(2, 0)
> > +#define REQ_CTRL_HOLDOFF(n)		((n) & REQ_CTRL_HOLDOFF_MASK)
> 
> Everything here is FDMA_ so why not these as well
> 
Everything apart from this and NODE_CTRL_*. I will add FDMA_ prefix to all in
v5.

regards,

Peter.

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

* [PATCH v4 05/18] dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file
@ 2016-06-06 17:40       ` Peter Griffin
  0 siblings, 0 replies; 113+ messages in thread
From: Peter Griffin @ 2016-06-06 17:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vinod,

Thanks for reviewing.

On Mon, 06 Jun 2016, Vinod Koul wrote:

> On Wed, May 25, 2016 at 05:06:39PM +0100, Peter Griffin wrote:
> 
> > +/*
> > + * request control bits
> > + */
> > +#define REQ_CTRL_NUM_OPS_MASK		GENMASK(31, 24)
> > +#define REQ_CTRL_NUM_OPS(n)		(REQ_CTRL_NUM_OPS_MASK & ((n) << 24))
> > +#define REQ_CTRL_INITIATOR_MASK		BIT(22)
> > +#define	REQ_CTRL_INIT0			(0x0 << 22)
> > +#define	REQ_CTRL_INIT1			(0x1 << 22)
> 
> pls keep spaces or tabs, not both :(

Will fix in v5.

> 
> > +#define REQ_CTRL_INC_ADDR_ON		BIT(21)
> > +#define REQ_CTRL_DATA_SWAP_ON		BIT(17)
> > +#define REQ_CTRL_WNR			BIT(14)
> > +#define REQ_CTRL_OPCODE_MASK		GENMASK(7, 4)
> > +#define REQ_CTRL_OPCODE_LD_ST1		(0x0 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST2		(0x1 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST4		(0x2 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST8		(0x3 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST16		(0x4 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST32		(0x5 << 4)
> > +#define REQ_CTRL_OPCODE_LD_ST64		(0x6 << 4)
> > +#define REQ_CTRL_HOLDOFF_MASK		GENMASK(2, 0)
> > +#define REQ_CTRL_HOLDOFF(n)		((n) & REQ_CTRL_HOLDOFF_MASK)
> 
> Everything here is FDMA_ so why not these as well
> 
Everything apart from this and NODE_CTRL_*. I will add FDMA_ prefix to all in
v5.

regards,

Peter.

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

end of thread, other threads:[~2016-06-06 17:40 UTC | newest]

Thread overview: 113+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-25 16:06 [PATCH 00/18] Add support for FDMA DMA controller and xp70 rproc found on STi chipsets Peter Griffin
2016-05-25 16:06 ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 " Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 01/18] remoteproc: st_xp70_rproc: add a xp70 slimcore rproc driver Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 17:10   ` Bjorn Andersson
2016-05-25 17:10     ` Bjorn Andersson
2016-06-06  7:22     ` Peter Griffin
2016-06-06  7:22       ` Peter Griffin
2016-05-27 13:15   ` Patrice Chotard
2016-05-27 13:15     ` Patrice Chotard
2016-05-27 13:15     ` Patrice Chotard
2016-05-27 16:13     ` Peter Griffin
2016-05-27 16:13       ` Peter Griffin
2016-05-27 16:13       ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 02/18] ARM: multi_v7_defconfig: enable st xp70 " Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 03/18] MAINTAINERS: Add st xp70 rproc driver to STi section Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 04/18] dmaengine: st_fdma: Add STMicroelectronics FDMA DT binding documentation Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-27 15:44   ` Rob Herring
2016-05-27 15:44     ` Rob Herring
2016-05-27 15:44     ` Rob Herring
2016-05-25 16:06 ` [PATCH v4 05/18] dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-06-06  4:36   ` Vinod Koul
2016-06-06  4:36     ` Vinod Koul
2016-06-06 17:40     ` Peter Griffin
2016-06-06 17:40       ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 06/18] dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 17:27   ` Bjorn Andersson
2016-05-25 17:27     ` Bjorn Andersson
2016-06-06  4:54   ` Vinod Koul
2016-06-06  4:54     ` Vinod Koul
2016-06-06  4:54     ` Vinod Koul
2016-06-06 17:38     ` Peter Griffin
2016-06-06 17:38       ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 07/18] ARM: STi: DT: STiH407: Add FDMA driver dt nodes Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 08/18] MAINTAINERS: Add FDMA driver files to STi section Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 09/18] ARM: multi_v7_defconfig: Enable STi FDMA driver Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 10/18] ASoC: sti: Update DT example to match the driver code Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-27 15:47   ` Rob Herring
2016-05-27 15:47     ` Rob Herring
2016-05-27 15:47     ` Rob Herring
2016-05-27 17:14   ` Mark Brown
2016-05-27 17:14     ` Mark Brown
2016-06-03 13:05     ` Peter Griffin
2016-06-03 13:05       ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 11/18] ARM: multi_v7_defconfig: Enable STi and simple-card drivers Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-31  8:55   ` Arnaud Pouliquen
2016-05-31  8:55     ` Arnaud Pouliquen
2016-05-31  8:55     ` Arnaud Pouliquen
2016-06-03 12:39     ` Peter Griffin
2016-06-03 12:39       ` Peter Griffin
2016-06-03 12:39       ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 12/18] ARM: DT: STiH407: Add i2s_out pinctrl configuration Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 13/18] ARM: DT: STiH407: Add i2s_in " Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 14/18] ARM: DT: STiH407: Add spdif_out pinctrl config Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 15/18] ARM: STi: DT: STiH407: Add sti-sasg-codec dt node Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-31  9:05   ` Arnaud Pouliquen
2016-05-31  9:05     ` Arnaud Pouliquen
2016-05-31  9:05     ` Arnaud Pouliquen
2016-06-03 13:00     ` Peter Griffin
2016-06-03 13:00       ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 16/18] ARM: STi: DT: STiH407: Add uniperif player dt nodes Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-31  9:14   ` Arnaud Pouliquen
2016-05-31  9:14     ` Arnaud Pouliquen
2016-05-31  9:14     ` Arnaud Pouliquen
2016-05-31  9:14     ` Arnaud Pouliquen
2016-06-03 12:56     ` Peter Griffin
2016-06-03 12:56       ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 17/18] ARM: STi: DT: STiH407: Add uniperif reader " Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-31  9:18   ` Arnaud Pouliquen
2016-05-31  9:18     ` Arnaud Pouliquen
2016-05-31  9:18     ` Arnaud Pouliquen
2016-06-03 12:50     ` Peter Griffin
2016-06-03 12:50       ` Peter Griffin
2016-06-03 12:50       ` Peter Griffin
2016-05-25 16:06 ` [PATCH v4 18/18] ARM: DT: STi: stihxxx-b2120: Add DT nodes for STi audio card Peter Griffin
2016-05-25 16:06   ` Peter Griffin
2016-05-31 10:16   ` Arnaud Pouliquen
2016-05-31 10:16     ` Arnaud Pouliquen
2016-05-31 10:16     ` Arnaud Pouliquen
2016-06-03 12:47     ` Peter Griffin
2016-06-03 12:47       ` Peter Griffin
2016-06-06  5:01 ` [PATCH 00/18] Add support for FDMA DMA controller and xp70 rproc found on STi chipsets Vinod Koul
2016-06-06  5:01   ` Vinod Koul
2016-06-06  5:01   ` Vinod Koul
2016-06-06 15:09   ` Peter Griffin
2016-06-06 15:09     ` Peter Griffin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.