Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* qcom: add firmware file for Venus on SDM845
From: Josh Boyer @ 2018-05-25 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527246209-26685-2-git-send-email-vgarodia@codeaurora.org>

On Fri, May 25, 2018 at 7:03 AM Vikash Garodia <vgarodia@codeaurora.org>
wrote:

> This pull request adds firmware files for Venus h/w codec found on the
Qualcomm SDM845 chipset.

> The following changes since commit
2a9b2cf50fb32e36e4fc1586c2f6f1421913b553:

>    Merge branch 'for-upstreaming-v1.7.2' of
https://github.com/felix-cavium/linux-firmware (2018-05-18 08:35:22 -0400)

> are available in the git repository at:


>    https://github.com/vgarodia/linux-firmware master

> for you to fetch changes up to d6088b9c9d7f49d3c6c43681190889eca0abdcce:

>    qcom: add venus firmware files for v5.2 (2018-05-25 15:16:43 +0530)

> ----------------------------------------------------------------
> Vikash Garodia (1):
>        qcom: add venus firmware files for v5.2

>   WHENCE                   |   9 +++++++++
>   qcom/venus-5.2/venus.b00 | Bin 0 -> 212 bytes
>   qcom/venus-5.2/venus.b01 | Bin 0 -> 6600 bytes
>   qcom/venus-5.2/venus.b02 | Bin 0 -> 819552 bytes
>   qcom/venus-5.2/venus.b03 | Bin 0 -> 33536 bytes
>   qcom/venus-5.2/venus.b04 |   1 +
>   qcom/venus-5.2/venus.mbn | Bin 0 -> 865408 bytes
>   qcom/venus-5.2/venus.mdt | Bin 0 -> 6812 bytes
>   8 files changed, 10 insertions(+)
>   create mode 100644 qcom/venus-5.2/venus.b00
>   create mode 100644 qcom/venus-5.2/venus.b01
>   create mode 100644 qcom/venus-5.2/venus.b02
>   create mode 100644 qcom/venus-5.2/venus.b03
>   create mode 100644 qcom/venus-5.2/venus.b04
>   create mode 100644 qcom/venus-5.2/venus.mbn
>   create mode 100644 qcom/venus-5.2/venus.mdt

The venus.mbn file isn't mentioned in WHENCE:

[jwboyer at vader linux-firmware]$ ./check_whence.py
E: qcom/venus-5.2/venus.mbn not listed in WHENCE
[jwboyer at vader linux-firmware]$

Can you fix that up and let me know when to re-pull?

josh

^ permalink raw reply

* [GIT PULL] Renesas ARM64 Based SoC Defconfig Updates for v4.18
From: Olof Johansson @ 2018-05-25 12:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1526548323.git.horms+renesas@verge.net.au>

On Fri, May 18, 2018 at 01:14:48PM +0200, Simon Horman wrote:
> Hi Olof, Hi Kevin, Hi Arnd,
> 
> Please consider these Renesas ARM64 based SoC defconfig updates for v4.18.
> 
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-arm64-defconfig-for-v4.18
> 
> for you to fetch changes up to c1fcd2ec1b1970e0e7b0c40c64bc51cf667b1a75:
> 
>   arm64: defconfig: enable R8A77990 SoC (2018-05-16 11:08:20 +0200)
> 
> ----------------------------------------------------------------
> Renesas ARM64 Based SoC Defconfig Updates for v4.18
> 
> * Enable in ARM64 defconfig:
>   - Recently mainlined support for R-Car E3 (r8a77990) SoC
> 
>   - HDMI sound and depdencies.
> 
>     HDMI sound is used by R-Car Gen 3.  These options are enabled as
>     modules to avoid unnecesesarily enlarging the kernel image.

Thanks, merged.


-Olof

^ permalink raw reply

* [GIT PULL 1/5] dt-bindings: tegra: Changes for v4.18-rc1
From: Olof Johansson @ 2018-05-25 12:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-1-thierry.reding@gmail.com>

On Fri, May 18, 2018 at 04:22:41PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-dt-bindings
> 
> for you to fetch changes up to eb8f53b6d3125894e3d825976eb7e03150496362:
> 
>   dt-bindings: Relocate Tegra20 memory controller bindings (2018-04-27 11:15:51 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> dt-bindings: tegra: Changes for v4.18-rc1
> 
> This contains the device tree bindings updates for the memory controller
> hot resets that are implemented by driver patches in a different branch.
> 
> ----------------------------------------------------------------
> Dmitry Osipenko (3):
>       dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding
>       dt-bindings: memory: tegra: Document #reset-cells property of the Tegra30 MC
>       dt-bindings: arm: tegra: Document #reset-cells property of the Tegra20 MC
> 
> Thierry Reding (1):
>       dt-bindings: Relocate Tegra20 memory controller bindings

Merged, thanks!


-Olof

^ permalink raw reply

* [GIT PULL 2/5] memory: tegra: Changes for v4.18-rc1
From: Olof Johansson @ 2018-05-25 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-2-thierry.reding@gmail.com>

On Fri, May 18, 2018 at 04:22:42PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-memory
> 
> for you to fetch changes up to bef89a8d81ca97aca864778746b110cf52847868:
> 
>   memory: tegra: Remove Tegra114 SATA and AFI reset definitions (2018-05-18 12:33:02 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> memory: tegra: Changes for v4.18-rc1
> 
> This contains some cleanup of the memory controller driver as well as
> unification work to share more code between Tegra20 and later SoC
> generations. Also included are an implementation for the hot resets
> functionality by the memory controller which is required to properly
> reset busy hardware.
> 
> ----------------------------------------------------------------
> Dmitry Osipenko (14):
>       dt-bindings: memory: tegra: Add hot resets definitions
>       memory: tegra: Do not handle spurious interrupts
>       memory: tegra: Setup interrupts mask before requesting IRQ
>       memory: tegra: Apply interrupts mask per SoC
>       memory: tegra: Remove unused headers inclusions
>       memory: tegra: Squash tegra20-mc into common tegra-mc driver
>       memory: tegra: Introduce memory client hot reset
>       memory: tegra: Add Tegra20 memory controller hot resets
>       memory: tegra: Add Tegra30 memory controller hot resets
>       memory: tegra: Add Tegra114 memory controller hot resets
>       memory: tegra: Add Tegra124 memory controller hot resets
>       memory: tegra: Register SMMU after MC driver became ready
>       dt-bindings: memory: tegra: Remove Tegra114 SATA and AFI reset definitions
>       memory: tegra: Remove Tegra114 SATA and AFI reset definitions
> 
> Thierry Reding (1):
>       memory: tegra: Add Tegra210 memory controller hot resets

Looks like this is just additional/proper resets, are there any backwards
compatibility concerns with older device trees or new assumptions of properties
that should be handled?


-Olof

^ permalink raw reply

* [PATCH v2 5/5] MAINTAINERS: Add Actions Semi S900 pinctrl entries
From: Linus Walleij @ 2018-05-25 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180525050103.3hg3u2v5mvftqhht@linaro.org>

On Fri, May 25, 2018 at 7:01 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> FYI, I have ordered S700 based Cubieboard and will work on adding support for
> that first. I still don't have access to S500 board yet since it is not
> available on my region. Will find a way to get this asap.

Awesome, then we can count on some actions action here.

>> Also I had been investing efforts in explaining the upstreaming process
>> to Actions, last in November. I see Thomas Liau and Jeff Chen missing in
>> CC and I have not seen any Reviewed-by or Acked-by from anyone at
>> Actions on this and the preceding series. There are more chips than the
>> one on Linaro's 96board, so I would prefer to assure that the design
>> works for all. Thus I am very critical of you applying the patches
>> without waiting for review by Actions.
>
> I don't think Actions would be interested in any upstreaming efforts. It
> is our (comunity) responsibility to add support for that in order to
> have our boards running mainline kernel and that's what we both have been
> doing. Moreover I only saw once David Liau responded to your patchset and
> there isn't much further. So how can you expect the subsystem maintainer's
> to hold the patch series waiting for a so far silent SoC manufacturer's
> response?

They are certainly informed now! :D

Actions semi folks, please familiarize yourself with the following:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git/tree/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt?h=devel
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git/tree/drivers/pinctrl/actions?h=devel

If you have any concerns with this, now is a good time to share them.

> I
> did ask you to add me as Co-Maintainer but you didn't responded to that.
> I know that I can't send any pull requests to Arnd, but we should sort
> it out IMO. Also, if you are completely swamped, then I take take up the
> maintainership role now inorder to keep the things moving. TBH I don't
> want my patches to be floating for months without any reason.

Doing some comainatinership can very well include doing pull
requests as long as you agree on who does what.

I think it may be a bit late for the next merge window right now,
but if you simply queue up stuff in some git tree and ask
Srothwell to include it in linux-next then Andreas can very well
pull it to his tree from there and then to ARM SoC or you can
queue patches as well.

Yours,
Linus Walleij

^ permalink raw reply

* [GIT PULL 2/5] memory: tegra: Changes for v4.18-rc1
From: Olof Johansson @ 2018-05-25 12:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518204351.GA26800@ulmo>

On Fri, May 18, 2018 at 10:43:51PM +0200, Thierry Reding wrote:
> On Fri, May 18, 2018 at 04:22:42PM +0200, Thierry Reding wrote:
> > Hi ARM SoC maintainers,
> > 
> > The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> > 
> >   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> > 
> > are available in the Git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-memory
> > 
> > for you to fetch changes up to bef89a8d81ca97aca864778746b110cf52847868:
> > 
> >   memory: tegra: Remove Tegra114 SATA and AFI reset definitions (2018-05-18 12:33:02 +0200)
> > 
> > Thanks,
> > Thierry
> > 
> > ----------------------------------------------------------------
> > memory: tegra: Changes for v4.18-rc1
> > 
> > This contains some cleanup of the memory controller driver as well as
> > unification work to share more code between Tegra20 and later SoC
> > generations. Also included are an implementation for the hot resets
> > functionality by the memory controller which is required to properly
> > reset busy hardware.
> > 
> > ----------------------------------------------------------------
> > Dmitry Osipenko (14):
> >       dt-bindings: memory: tegra: Add hot resets definitions
> >       memory: tegra: Do not handle spurious interrupts
> >       memory: tegra: Setup interrupts mask before requesting IRQ
> >       memory: tegra: Apply interrupts mask per SoC
> >       memory: tegra: Remove unused headers inclusions
> >       memory: tegra: Squash tegra20-mc into common tegra-mc driver
> >       memory: tegra: Introduce memory client hot reset
> >       memory: tegra: Add Tegra20 memory controller hot resets
> >       memory: tegra: Add Tegra30 memory controller hot resets
> >       memory: tegra: Add Tegra114 memory controller hot resets
> >       memory: tegra: Add Tegra124 memory controller hot resets
> >       memory: tegra: Register SMMU after MC driver became ready
> >       dt-bindings: memory: tegra: Remove Tegra114 SATA and AFI reset definitions
> >       memory: tegra: Remove Tegra114 SATA and AFI reset definitions
> 
> Please don't pull this just yet. Dmitry just pointed out to me that the
> final two patches here break bisectibility. I'll reorder them and will
> send out a new pull request.

Please delete the tag when you withdraw a pull request, and do the next request
with a new tag name. That way I don't have to scan my mailbox to make sure all
pull requests are still valid when I go through it and won't accidentally merge
something that you have withdrawn.


-Olof

^ permalink raw reply

* [PATCH] drm/rockchip: vop: fix irq disabled after vop driver probed
From: Heiko Stuebner @ 2018-05-25 12:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8495bffd-2a52-ca85-1bc9-afc3ea0af8e4@arm.com>

Hi Marc,

Am Freitag, 25. Mai 2018, 13:07:02 CEST schrieb Marc Zyngier:
> [Thanks Robin for pointing me to that patch.]
> 
> Hi Heiko,
> 
> On 24/05/18 23:06, Heiko St?bner wrote:
> > From: Sandy Huang <hjc@rock-chips.com>
> > 
> > The vop irq is shared between vop and iommu and irq probing in the
> > iommu driver moved to the probe function recently. This can in some
> > cases lead to a stall if the irq is triggered while the vop driver
> > still has it disabled.
> > 
> > But there is no real need to disable the irq, as the vop can simply
> > also track its enabled state and ignore irqs in that case.
> > 
> > So remove the enable/disable handling and add appropriate condition
> > to the irq handler.
> > 
> > Signed-off-by: Sandy Huang <hjc@rock-chips.com>
> > [added an actual commit message]
> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> > ---
> > Hi Ezequiel,
> > 
> > this patch came from a discussion I had with Rockchip people over the
> > iommu changes and resulting issues back in april, but somehow was
> > forgotten and not posted to the lists. Correcting that now.
> > 
> > So removing the enable/disable voodoo on the shared interrupt is
> > the preferred way.
> > 
> >  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++++++-------
> >  1 file changed, 7 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > index 510cdf0..61493d4 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > @@ -549,8 +549,6 @@ static int vop_enable(struct drm_crtc *crtc)
> >  
> >  	spin_unlock(&vop->reg_lock);
> >  
> > -	enable_irq(vop->irq);
> > -
> >  	drm_crtc_vblank_on(crtc);
> >  
> >  	return 0;
> > @@ -596,8 +594,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
> >  
> >  	vop_dsp_hold_valid_irq_disable(vop);
> >  
> > -	disable_irq(vop->irq);
> > -
> >  	vop->is_enabled = false;
> >  
> >  	/*
> > @@ -1168,6 +1164,13 @@ static irqreturn_t vop_isr(int irq, void *data)
> >  	int ret = IRQ_NONE;
> >  
> >  	/*
> > +	 * since the irq is shared with iommu, iommu irq is enabled before vop
> > +	 * enable, so before vop enable we do nothing.
> > +	 */
> > +	if (!vop->is_enabled)
> > +		return IRQ_NONE;
> > +
> 
> What guarantee do we have that the IOMMU will actually service that
> interrupt? Can't we get into a situation where the interrupt gets
> ignored by both drivers and subsequently disabled by the core irq code
> as being spurious?
> 
> From what I understood of the way things are plugged together on the
> rockchip platforms, each individual VOP is behind a single IOMMU, hence
> there there is hardly any point in handling IOMMU interrupts if the VOP
> is off.

Yeah, which is probably the reason that patch fell through the cracks
initially. I resurrected it from the internal discussion because of the issue
described below.

> But I'm missing the actual reason behind this patch. Could you enlighten me?

Recently the iommu driver moved the irq request from the iommu enablement
to its probe function. With that change Ezequiel got various stalls, see
	https://lkml.org/lkml/2018/5/24/1347


Heiko

^ permalink raw reply

* [GIT PULL v2 2/5] memory: tegra: Changes for v4.18-rc1
From: Olof Johansson @ 2018-05-25 12:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518215837.29076-1-thierry.reding@gmail.com>

On Fri, May 18, 2018 at 11:58:37PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-memory-v2
> 
> for you to fetch changes up to a1be3cfdfb81cc55c1b2feb73aca6945f61acddb:
> 
>   dt-bindings: memory: tegra: Remove Tegra114 SATA and AFI reset definitions (2018-05-18 22:45:01 +0200)
> 
> This contains the same patches as the previous pull request with the exception
> that the final two are reordered to keep the set bisectible.
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> memory: tegra: Changes for v4.18-rc1
> 
> This contains some cleanup of the memory controller driver as well as
> unification work to share more code between Tegra20 and later SoC
> generations. Also included are an implementation for the hot resets
> functionality by the memory controller which is required to properly
> reset busy hardware.
> 
> ----------------------------------------------------------------
> Dmitry Osipenko (14):
>       dt-bindings: memory: tegra: Add hot resets definitions
>       memory: tegra: Do not handle spurious interrupts
>       memory: tegra: Setup interrupts mask before requesting IRQ
>       memory: tegra: Apply interrupts mask per SoC
>       memory: tegra: Remove unused headers inclusions
>       memory: tegra: Squash tegra20-mc into common tegra-mc driver
>       memory: tegra: Introduce memory client hot reset
>       memory: tegra: Add Tegra20 memory controller hot resets
>       memory: tegra: Add Tegra30 memory controller hot resets
>       memory: tegra: Add Tegra114 memory controller hot resets
>       memory: tegra: Add Tegra124 memory controller hot resets
>       memory: tegra: Register SMMU after MC driver became ready
>       memory: tegra: Remove Tegra114 SATA and AFI reset definitions
>       dt-bindings: memory: tegra: Remove Tegra114 SATA and AFI reset definitions
> 
> Thierry Reding (1):
>       memory: tegra: Add Tegra210 memory controller hot resets

Merged, thanks.


-Olof

^ permalink raw reply

* [GIT PULL 3/5] ARM: tegra: Core changes for v4.18-rc1
From: Olof Johansson @ 2018-05-25 12:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-3-thierry.reding@gmail.com>

On Fri, May 18, 2018 at 04:22:43PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-arm-soc
> 
> for you to fetch changes up to 15164e0072b579f77c9025f3da3ed931869b89cd:
> 
>   ARM: tegra: Create platform device for tegra20-cpufreq driver (2018-05-18 11:15:42 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> ARM: tegra: Core changes for v4.18-rc1
> 
> Contains a single patch that instantiates a platform device for the CPU
> frequency driver.

Merged, thanks.


-Olof

^ permalink raw reply

* [GIT PULL 4/5] ARM: tegra: Device tree changes for v4.18-rc1
From: Olof Johansson @ 2018-05-25 12:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-4-thierry.reding@gmail.com>

On Fri, May 18, 2018 at 04:22:44PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-arm-dt
> 
> for you to fetch changes up to dc4ea601be724d7ad37c8c5b1059417126e97e27:
> 
>   ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients (2018-05-04 17:21:02 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> ARM: tegra: Device tree changes for v4.18-rc1
> 
> Contains a fix for the high-speed UART on Toradex Apalis TK1 boards as
> well as IOMMU enablement for various devices on Tegra30 and Tegra30.
> 
> ----------------------------------------------------------------
> Dmitry Osipenko (2):
>       ARM: dts: tegra30: Add IOMMU nodes to Host1x and its clients
>       ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients
> 
> Marcel Ziswiler (1):
>       ARM: tegra: apalis-tk1: Fix high speed UART compatible

Merged, thanks!


-Olof

^ permalink raw reply

* [GIT PULL 5/5] arm64: tegra: Device tree changes for v4.18-rc1
From: Olof Johansson @ 2018-05-25 12:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-5-thierry.reding@gmail.com>

On Fri, May 18, 2018 at 04:22:45PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-arm64-dt
> 
> for you to fetch changes up to 9df50ba76ac1485b844beffa1f3f5d9659d9cdaf:
> 
>   arm64: tegra: Make BCM89610 PHY interrupt as active low (2018-05-03 11:48:16 +0200)
> 
> I already sent this out as a fix for v4.17, so if you decide to pick
> that up you can ignore this one. I've only included it here in case you
> had objections to take it into v4.17 at this point.

Ok, thanks -- merged the fix so not touching this.


-Olof

^ permalink raw reply

* [GIT PULL] ARM: mvebu: arm64 for v4.18 (#1)
From: Olof Johansson @ 2018-05-25 12:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <874lj429kq.fsf@bootlin.com>

On Fri, May 18, 2018 at 06:49:09PM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the first pull request for arm64 for mvebu for v4.18.
> 
> Gregory
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-arm64-4.18-1
> 
> for you to fetch changes up to 3eb0a48af488b5e83d2986943a1b6905ca753571:
> 
>   arm64: defconfig: enable the Armada thermal driver (2018-05-16 20:08:31 +0200)

Merged, thanks!


-Olof

^ permalink raw reply

* [PATCH v3 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd
From: Radu Pirea @ 2018-05-25 12:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4d70c73e-9db7-bdff-7414-04a4843acae3@sorico.fr>



On 05/15/2018 04:14 PM, Richard Genoud wrote:
> On 15/05/2018 14:47, Radu Pirea wrote:
>> On Mon, 2018-05-14 at 12:57 +0200, Richard Genoud wrote:
>>> After your patch, the DMA is not selected anymore:
>>> atmel_usart_serial atmel_usart_serial.0.auto: TX channel not
>>> available, switch to pio
>>> instead of:
>>> atmel_usart fffff200.serial: using dma1chan2 for tx DMA transfers
>>>
>> Fixed.
>>> And the kernel doesn't log anymore on the serial console, despite the
>>> loglevel=8
>>> (after reverting this series, the kernel logs reappears on the serial
>>> console)
>>>
>> Which serial are you using as console?
> fffff200.serial (sam9g35-cm)
> ( stdout-path = "serial0:115200n8"; in the DTS )
> 
> With this series applied, all the kernel log goes on the screen.
> Without, it goes on the serial debug.
> 
I tested again with archlinux arm and poky-linux4sam release as distros 
and kernel log goes on the serial debug. Can you give me more details 
like cmdline?
>>> (tests done on sam9g35)
>>>
>> I will consider the rest of suggestions.
>>> regards,
>>> Richard
> 

^ permalink raw reply

* [GIT PULL] ARM: mvebu: dt for v4.18 (#1)
From: Olof Johansson @ 2018-05-25 12:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8736yo29jb.fsf@bootlin.com>

On Fri, May 18, 2018 at 06:50:00PM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the first pull request for dt for mvebu for v4.18.
> 
> Gregory
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-dt-4.18-1
> 
> for you to fetch changes up to 163043ab55210dbb92e36c1220a721f404df6834:
> 
>   ARM: dts: armada-xp-98dx: Add NAND pinctrl information (2018-05-18 18:36:57 +0200)

Definitely a pretty noisy pull request, but it's a good move from the format
that requires mimicing the tree structure and using phandles instead.

Merged!


-Olof

^ permalink raw reply

* [GIT PULL] ARM: mvebu: dt64 for v4.18 (#1)
From: Olof Johansson @ 2018-05-25 12:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <871se829iq.fsf@bootlin.com>

On Fri, May 18, 2018 at 06:50:21PM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the first pull request for dt64 for mvebu for v4.18.
> 
> Gregory
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-dt64-4.18-1
> 
> for you to fetch changes up to bd473ecda24c6214868d58500c4d7569f6597946:
> 
>   arm64: dts: marvell: armada-37xx: mark the gpio controllers as irq controller (2018-05-18 18:35:16 +0200)

Merged, thanks!


-Olof

^ permalink raw reply

* [PATCH v2 1/8] driver core: make deferring probe after init optional
From: Robin Murphy @ 2018-05-25 12:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL_JsqJK69A3W=YrSfvPetM95CROOJhU1bW1rMEOGtji=t0ORQ@mail.gmail.com>

On 24/05/18 21:57, Rob Herring wrote:
> On Thu, May 24, 2018 at 2:00 PM, Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
>> On Thu, May 24, 2018 at 12:50:17PM -0500, Rob Herring wrote:
>>> Deferred probe will currently wait forever on dependent devices to probe,
>>> but sometimes a driver will never exist. It's also not always critical for
>>> a driver to exist. Platforms can rely on default configuration from the
>>> bootloader or reset defaults for things such as pinctrl and power domains.
>>> This is often the case with initial platform support until various drivers
>>> get enabled. There's at least 2 scenarios where deferred probe can render
>>> a platform broken. Both involve using a DT which has more devices and
>>> dependencies than the kernel supports. The 1st case is a driver may be
>>> disabled in the kernel config. The 2nd case is the kernel version may
>>> simply not have the dependent driver. This can happen if using a newer DT
>>> (provided by firmware perhaps) with a stable kernel version.
>>>
>>> Subsystems or drivers may opt-in to this behavior by calling
>>> driver_deferred_probe_check_init_done() instead of just returning
>>> -EPROBE_DEFER. They may use additional information from DT or kernel's
>>> config to decide whether to continue to defer probe or not.
>>>
>>> Cc: Alexander Graf <agraf@suse.de>
>>> Signed-off-by: Rob Herring <robh@kernel.org>
>>> ---
>>>   drivers/base/dd.c      | 17 +++++++++++++++++
>>>   include/linux/device.h |  2 ++
>>>   2 files changed, 19 insertions(+)
>>>
>>> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
>>> index c9f54089429b..d6034718da6f 100644
>>> --- a/drivers/base/dd.c
>>> +++ b/drivers/base/dd.c
>>> @@ -226,6 +226,16 @@ void device_unblock_probing(void)
>>>        driver_deferred_probe_trigger();
>>>   }
>>>
>>> +int driver_deferred_probe_check_init_done(struct device *dev, bool optional)
>>> +{
>>> +     if (optional && initcalls_done) {
>>
>> Wait, what's the "optional" mess here?
> 
> My intent was that subsystems just always call this function and never
> return EPROBE_DEFER themselves. Then the driver core can make
> decisions as to what to do (such as the timeout added in the next
> patch). Or it can print common error/debug messages. So optional is a
> hint to allow subsystems per device control.

Maybe just driver_defer_probe() might be a more descriptive name? To me, 
calling "foo_check_x()" with a parameter that says "I don't actually 
care about x" is the really unintuitive bit.

>>
>> The caller knows this value, so why do you need to even pass it in here?
> 
> Because regardless of the value, we always stop deferring when/if we
> hit the timeout and the caller doesn't know about the timeout. If we
> get rid of it, we'd need functions for both init done and for deferred
> timeout.
> 
>> And bool values that are not obvious are horrid.  I had to go look this
>> up when reading the later patches that just passed "true" in this
>> variable as I had no idea what that meant.
> 
> Perhaps inverting it and calling it "keep_deferring" would be better.
> However, the flag is ignored if we have timed out.

Perhaps an enum (or bitmask of named flags) then? That would allow the 
most readability at callsites, plus it seems quite likely that we may 
want intermediate degrees of "deferral strictness" eventually.

Robin.

>>
>> So as-is, no, this isn't ok, sorry.
>>
>> And at the least, this needs some kerneldoc to explain it :)
> 
> That part is easy enough to fix.
> 
> Rob
> 

^ permalink raw reply

* [GIT PULL] ARM: dts: uniphier: UniPhier DT updates for v4.18
From: Olof Johansson @ 2018-05-25 12:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK7LNATphrRyYvMXMMJz--UtfNk2BZLWHAp3XXpQLob5=5w2Qg@mail.gmail.com>

On Sun, May 20, 2018 at 11:34:08AM +0900, Masahiro Yamada wrote:
> Hi Arnd, Olof,
> 
> Here are UniPhier DT (32bit) updates for the v4.18 merge window.
> Please pull!
> 
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier.git
> tags/uniphier-dt-v4.18
> 
> for you to fetch changes up to 526f872b8492fbfb1a0f342e601bdc5ba322f16b:
> 
>   ARM: dts: uniphier: add syscon-phy-mode property to each ethernet
> node (2018-04-25 00:21:51 +0900)
> 
> ----------------------------------------------------------------
> UniPhier ARM SoC DT updates for v4.18
> 
> - add more properties to ethernet nodes
> 
> ----------------------------------------------------------------
> Kunihiko Hayashi (2):
>       ARM: dts: uniphier: add required clocks and resets to Pro4 ethernet node
>       ARM: dts: uniphier: add syscon-phy-mode property to each ethernet node

Hi,

Merged, but please spend a little more effort on the tag description (what are
these new properties giving you in functionality?)


-Olof

^ permalink raw reply

* [GIT PULL] arm64: dts: uniphier: UniPhier DT updates for v4.18
From: Olof Johansson @ 2018-05-25 12:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK7LNASUq_9osPdzbiMCbYzeqc=W3Yv7tB63V+5gXqcZ9QBtYA@mail.gmail.com>

On Sun, May 20, 2018 at 11:38:39AM +0900, Masahiro Yamada wrote:
> Hi Arnd, Olof,
> 
> Here are UniPhier DT (64bit) updates for the v4.18 merge window.
> Please pull!
> 
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier.git
> tags/uniphier-dt64-v4.18
> 
> for you to fetch changes up to b076ff8bddfba793d49bca14feb49a0e84f41843:
> 
>   arm64: dts: uniphier: add syscon-phy-mode property to each ethernet
> node (2018-04-25 00:21:14 +0900)
> 
> ----------------------------------------------------------------
> UniPhier ARM64 SoC DT updates for v4.18
> 
> - add more properties to ethernet nodes
> 
> ----------------------------------------------------------------
> Kunihiko Hayashi (2):
>       arm64: dts: uniphier: add clock-names and reset-names to ethernet node
>       arm64: dts: uniphier: add syscon-phy-mode property to each ethernet node

Merged, same comment as for the 32-bit pull request. Thanks!


-Olof

^ permalink raw reply

* [PATCH 9/9] PM / Domains: Add dev_pm_domain_attach_by_id() to manage multi PM domains
From: Ulf Hansson @ 2018-05-25 12:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b3a94d63-678c-eab6-47a8-43eca95da979@nvidia.com>

On 25 May 2018 at 13:07, Jon Hunter <jonathanh@nvidia.com> wrote:
>
>
> On 25/05/18 11:45, Ulf Hansson wrote:
>
> ...
>
>>> Right, but this case still seems like an error. My understanding is that
>>> only drivers will use this API directly and it will not be used by the
>>> device driver core (unlike dev_pm_domain_attach), so if anyone calls this
>>> attempting to attach another PM domain when one is already attached, they
>>> are doing something wrong.
>>
>>
>> [...]
>>
>> You may be right!
>>
>> What I was thinking of is whether multiple PM domains may be optional
>> in some cases, but instead a PM domain have already been attached by
>> dev_pm_domain_attach(), prior the driver starts to probe.
>>
>> Then, assuming we return an error for this case, that means the caller
>> then need to check the dev->pm_domain pointer, prior calling
>> dev_pm_domain_attach_by_id(). Wouldn't it? Perhaps that is more clear
>> though?
>
>
> IMO the driver should know whether is needs multiple power-domains or not
> and if it needs multiple then it should just call
> dev_pm_domain_attach_by_id() N times without needing to checking
> dev->pm_domain first. If it fails then either the PM domain core did
> something wrong or power-domains are missing from DT, but either way there
> is an error, so let it fail.

Right, sounds reasonable!

Kind regards
Uffe

^ permalink raw reply

* [PATCH v4 0/7] ASoC: add driver for Atmel I2S controller
From: Codrin Ciubotariu @ 2018-05-25 12:34 UTC (permalink / raw)
  To: linux-arm-kernel

This is a rework of Cyrille's patches named:
[PATCH v3 0/2] ASoC: add driver for Atmel I2S controller
https://lkml.org/lkml/2015/9/29/454

This is the version 4 of the series, and addresses the received feedback
on the mailing lists.

This series applies on top of asoc-next branch of broonie/sound.git.

Based on received feedback, I created a mux clock driver to select the I2S
clock source, that also includes proper devicetree bindings and nodes.
Also, I added the I2S nodes in sama5d2's devicetree, with the missing
pin muxing for the second I2S controller.

This series of patches adds support to the new Atmel I2S controller
embedded on sama5d2 SoCs.

ChangeLog

v3 -> v4
 - as suggested by Rob Herring:
   - added a clock mux driver for I2S's clock control bit;
   - more precise description of I2S's devicetree bindings;
   - removed SoC and internal detalls from bindings;
 - addressed comments from Mark Brown;
 - added devicetree nodes and pin muxing for I2S;

v2 -> v3
- fix the coding style, add some more comments and add a section dedicated
  to sama5d2 SoCs in the DT binding documentation as suggested by Mark
  Brown.

v1 -> v2
- initialize dev->dev before calling dev->caps->mck_init()


Codrin Ciubotariu (3):
  dt-bindings: clk: at91: add an I2S mux clock
  clk: at91: add I2S clock mux driver
  ARM: dts: at91: sama5d2: add I2S clock muxing nodes

Cyrille Pitchen (4):
  ASoC: atmel-i2s: dt-bindings: add DT bindings for I2S controller
  ASoC: atmel-i2s: add driver for the new Atmel I2S controller
  ARM: dts: at91: sama5d2: add nodes for I2S controllers
  ARM: dts: at91: sama5d2 Xplained: add pin muxing for I2S

 .../devicetree/bindings/clock/at91-clock.txt       |  34 +
 .../devicetree/bindings/sound/atmel-i2s.txt        |  47 ++
 arch/arm/boot/dts/at91-sama5d2_xplained.dts        |  28 +
 arch/arm/boot/dts/sama5d2.dtsi                     |  52 ++
 arch/arm/mach-at91/Kconfig                         |   4 +
 drivers/clk/at91/Makefile                          |   1 +
 drivers/clk/at91/clk-i2s-mux.c                     | 117 ++++
 sound/soc/atmel/Kconfig                            |   9 +
 sound/soc/atmel/Makefile                           |   2 +
 sound/soc/atmel/atmel-i2s.c                        | 765 +++++++++++++++++++++
 10 files changed, 1059 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/atmel-i2s.txt
 create mode 100644 drivers/clk/at91/clk-i2s-mux.c
 create mode 100644 sound/soc/atmel/atmel-i2s.c

-- 
2.7.4

^ permalink raw reply

* [PATCH v4 1/7] dt-bindings: clk: at91: add an I2S mux clock
From: Codrin Ciubotariu @ 2018-05-25 12:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527251668-31396-1-git-send-email-codrin.ciubotariu@microchip.com>

The I2S mux clock can be used to select the I2S input clock. The
available parents are the peripheral and the generated clocks.

Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
---
 .../devicetree/bindings/clock/at91-clock.txt       | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index 51c259a..1c46b3c 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -90,6 +90,8 @@ Required properties:
 	"atmel,sama5d2-clk-audio-pll-pmc"
 		at91 audio pll output on AUDIOPLLCLK that feeds the PMC
 		and can be used by peripheral clock or generic clock
+	"atmel,sama5d2-clk-i2s-mux":
+		at91 I2S clock source selection
 
 Required properties for SCKC node:
 - reg : defines the IO memory reserved for the SCKC.
@@ -507,3 +509,35 @@ For example:
 			atmel,clk-output-range = <0 83000000>;
 		};
 	};
+
+Required properties for I2S mux clocks:
+- #size-cells : shall be 0 (reg is used to encode I2S bus id).
+- #address-cells : shall be 1 (reg is used to encode I2S bus id).
+- name: device tree node describing a specific mux clock.
+	* #clock-cells : from common clock binding; shall be set to 0.
+	* clocks : shall be the mux clock parent phandles; shall be 2 phandles:
+	  peripheral and generated clock; the first phandle shall belong to the
+	  peripheral clock and the second one shall belong to the generated
+	  clock; "clock-indices" property can be user to specify
+	  the correct order.
+	* reg: I2S bus id of the corresponding mux clock.
+	  e.g. reg = <0>; for i2s0, reg = <1>; for i2s1
+
+For example:
+	i2s_clkmux {
+		compatible = "atmel,sama5d2-clk-i2s-mux";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2s0muxck: i2s0_muxclk {
+			clocks = <&i2s0_clk>, <&i2s0_gclk>;
+			#clock-cells = <0>;
+			reg = <0>;
+		};
+
+		i2s1muxck: i2s1_muxclk {
+			clocks = <&i2s1_clk>, <&i2s1_gclk>;
+			#clock-cells = <0>;
+			reg = <1>;
+		};
+	};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v4 2/7] clk: at91: add I2S clock mux driver
From: Codrin Ciubotariu @ 2018-05-25 12:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527251668-31396-1-git-send-email-codrin.ciubotariu@microchip.com>

This driver is a simple muxing driver that controls the
I2S's clock input by using syscon/regmap to change the parrent.
The available inputs can be Peripheral clock and Generated clock.

Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
---
 arch/arm/mach-at91/Kconfig     |   4 ++
 drivers/clk/at91/Makefile      |   1 +
 drivers/clk/at91/clk-i2s-mux.c | 117 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+)
 create mode 100644 drivers/clk/at91/clk-i2s-mux.c

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 1254bf9..903f23c 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -27,6 +27,7 @@ config SOC_SAMA5D2
 	select HAVE_AT91_H32MX
 	select HAVE_AT91_GENERATED_CLK
 	select HAVE_AT91_AUDIO_PLL
+	select HAVE_AT91_I2S_MUX_CLK
 	select PINCTRL_AT91PIO4
 	help
 	  Select this if ou are using one of Microchip's SAMA5D2 family SoC.
@@ -129,6 +130,9 @@ config HAVE_AT91_GENERATED_CLK
 config HAVE_AT91_AUDIO_PLL
 	bool
 
+config HAVE_AT91_I2S_MUX_CLK
+	bool
+
 config SOC_SAM_V4_V5
 	bool
 
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 082596f..facc169 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_HAVE_AT91_USB_CLK)		+= clk-usb.o
 obj-$(CONFIG_HAVE_AT91_SMD)		+= clk-smd.o
 obj-$(CONFIG_HAVE_AT91_H32MX)		+= clk-h32mx.o
 obj-$(CONFIG_HAVE_AT91_GENERATED_CLK)	+= clk-generated.o
+obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK)	+= clk-i2s-mux.o
diff --git a/drivers/clk/at91/clk-i2s-mux.c b/drivers/clk/at91/clk-i2s-mux.c
new file mode 100644
index 0000000..2d56ded
--- /dev/null
+++ b/drivers/clk/at91/clk-i2s-mux.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright (C) 2018 Microchip Technology Inc,
+ *                     Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+ *
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include <soc/at91/atmel-sfr.h>
+
+#define	I2S_BUS_NR	2
+
+struct clk_i2s_mux {
+	struct clk_hw hw;
+	struct regmap *regmap;
+	u32 bus_id;
+};
+
+#define to_clk_i2s_mux(hw) container_of(hw, struct clk_i2s_mux, hw)
+
+static u8 clk_i2s_mux_get_parent(struct clk_hw *hw)
+{
+	struct clk_i2s_mux *mux = to_clk_i2s_mux(hw);
+	u32 val;
+
+	regmap_read(mux->regmap, AT91_SFR_I2SCLKSEL, &val);
+
+	return (val & BIT(mux->bus_id)) >> mux->bus_id;
+}
+
+static int clk_i2s_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_i2s_mux *mux = to_clk_i2s_mux(hw);
+
+	return regmap_update_bits(mux->regmap, AT91_SFR_I2SCLKSEL,
+				  BIT(mux->bus_id), index << mux->bus_id);
+}
+
+const struct clk_ops clk_i2s_mux_ops = {
+	.get_parent = clk_i2s_mux_get_parent,
+	.set_parent = clk_i2s_mux_set_parent,
+	.determine_rate = __clk_mux_determine_rate,
+};
+
+static struct clk_hw * __init
+at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
+			  const char * const *parent_names,
+			  unsigned int num_parents, u32 bus_id)
+{
+	struct clk_init_data init = {};
+	struct clk_i2s_mux *i2s_ck;
+	int ret;
+
+	i2s_ck = kzalloc(sizeof(*i2s_ck), GFP_KERNEL);
+	if (!i2s_ck)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_i2s_mux_ops;
+	init.parent_names = parent_names;
+	init.num_parents = num_parents;
+	init.flags = CLK_IGNORE_UNUSED;
+
+	i2s_ck->hw.init = &init;
+	i2s_ck->bus_id = bus_id;
+	i2s_ck->regmap = regmap;
+
+	ret = clk_hw_register(NULL, &i2s_ck->hw);
+	if (ret) {
+		kfree(i2s_ck);
+		return ERR_PTR(ret);
+	}
+
+	return &i2s_ck->hw;
+}
+
+static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
+{
+	struct regmap *regmap_sfr;
+	u32 bus_id;
+	const char *parent_names[2];
+	struct device_node *i2s_mux_np;
+	struct clk_hw *hw;
+	int ret;
+
+	regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
+	if (IS_ERR(regmap_sfr))
+		return;
+
+	for_each_child_of_node(np, i2s_mux_np) {
+		if (of_property_read_u32(i2s_mux_np, "reg", &bus_id))
+			continue;
+
+		if (bus_id > I2S_BUS_NR)
+			continue;
+
+		ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
+		if (ret != 2)
+			continue;
+
+		hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
+					       parent_names, 2, bus_id);
+		if (IS_ERR(hw))
+			continue;
+
+		of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw);
+	}
+}
+
+CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
+	       of_sama5d2_clk_i2s_mux_setup);
-- 
2.7.4

^ permalink raw reply related

* [PATCH v4 3/7] ARM: dts: at91: sama5d2: add I2S clock muxing nodes
From: Codrin Ciubotariu @ 2018-05-25 12:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527251668-31396-1-git-send-email-codrin.ciubotariu@microchip.com>

This patch adds two clock muxes for the two I2S
buses present on sama5d2 platforms.

Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
---
 arch/arm/boot/dts/sama5d2.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 61f68e5..eeb6afa 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -992,6 +992,24 @@
 						atmel,clk-output-range = <0 100000000>;
 					};
 				};
+
+				i2s_clkmux {
+					compatible = "atmel,sama5d2-clk-i2s-mux";
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					i2s0muxck: i2s0_muxclk {
+						clocks = <&i2s0_clk>, <&i2s0_gclk>;
+						#clock-cells = <0>;
+						reg = <0>;
+					};
+
+					i2s1muxck: i2s1_muxclk {
+						clocks = <&i2s1_clk>, <&i2s1_gclk>;
+						#clock-cells = <0>;
+						reg = <1>;
+					};
+				};
 			};
 
 			qspi0: spi at f0020000 {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v4 4/7] ASoC: atmel-i2s: dt-bindings: add DT bindings for I2S controller
From: Codrin Ciubotariu @ 2018-05-25 12:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527251668-31396-1-git-send-email-codrin.ciubotariu@microchip.com>

From: Cyrille Pitchen <cyrille.pitchen@atmel.com>

This patch adds DT bindings for the new Atmel I2S controller embedded
inside sama5d2x SoCs.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
---

Changes in v4:
	- more specific description for dmas, dma-names, clocks, clock-names
	  properties;
	- removed SoC and internal details of the block IP;
	- added description for the new clock mux phandle;

 .../devicetree/bindings/sound/atmel-i2s.txt        | 47 ++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/atmel-i2s.txt

diff --git a/Documentation/devicetree/bindings/sound/atmel-i2s.txt b/Documentation/devicetree/bindings/sound/atmel-i2s.txt
new file mode 100644
index 0000000..735368b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel-i2s.txt
@@ -0,0 +1,47 @@
+* Atmel I2S controller
+
+Required properties:
+- compatible:     Should be "atmel,sama5d2-i2s".
+- reg:            Should be the physical base address of the controller and the
+                  length of memory mapped region.
+- interrupts:     Should contain the interrupt for the controller.
+- dmas:           Should be one per channel name listed in the dma-names property,
+                  as described in atmel-dma.txt and dma.txt files.
+- dma-names:      Two dmas have to be defined, "tx" and "rx".
+                  This IP also supports one shared channel for both rx and tx;
+                  if this mode is used, one "rx-tx" name must be used.
+- clocks:         Must contain an entry for each entry in clock-names.
+                  Please refer to clock-bindings.txt.
+- clock-names:    Should be one of each entry matching the clocks phandles list:
+                  - "pclk" (peripheral clock) Required.
+                  - "gclk" (generated clock) Optional (1).
+                  - "aclk" (Audio PLL clock) Optional (1).
+                  - "muxclk" (I2S mux clock) Optional (1).
+
+Optional properties:
+- pinctrl-0:      Should specify pin control groups used for this controller.
+- princtrl-names: Should contain only one value - "default".
+
+
+(1) : Only the peripheral clock is required. The generated clock, the Audio
+      PLL clock adn the I2S mux clock are optional and should only be set
+      together, when Master Mode is required.
+
+Example:
+
+	i2s at f8050000 {
+		compatible = "atmel,sama5d2-i2s";
+		reg = <0xf8050000 0x300>;
+		interrupts = <54 IRQ_TYPE_LEVEL_HIGH 7>;
+		dmas = <&dma0
+			(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+			 AT91_XDMAC_DT_PERID(31))>,
+		       <&dma0
+			(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+			 AT91_XDMAC_DT_PERID(32))>;
+		dma-names = "tx", "rx";
+		clocks = <&i2s0_clk>, <&i2s0_gclk>, <&audio_pll_pmc>, <&i2s0muxck>;
+		clock-names = "pclk", "gclk", "aclk", "muxclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2s0_default>;
+	};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v4 5/7] ASoC: atmel-i2s: add driver for the new Atmel I2S controller
From: Codrin Ciubotariu @ 2018-05-25 12:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527251668-31396-1-git-send-email-codrin.ciubotariu@microchip.com>

From: Cyrille Pitchen <cyrille.pitchen@atmel.com>

This patch adds support for the Atmel I2S controller embedded into
sama5d2x SoCs.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
---

Changes in v4:
	- treated -EPROBE_DEFER on probe;
	- replaced ternary operator with if;
	- return -EINVAL if we don't support the number of audio channels.

 sound/soc/atmel/Kconfig     |   9 +
 sound/soc/atmel/Makefile    |   2 +
 sound/soc/atmel/atmel-i2s.c | 765 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 776 insertions(+)
 create mode 100644 sound/soc/atmel/atmel-i2s.c

diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index dcee145..64b784e 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -88,4 +88,13 @@ config SND_ATMEL_SOC_TSE850_PCM5142
 	help
 	  Say Y if you want to add support for the ASoC driver for the
 	  Axentia TSE-850 with a PCM5142 codec.
+
+config SND_ATMEL_SOC_I2S
+	tristate "Atmel ASoC driver for boards using I2S"
+	depends on OF && (ARCH_AT91 || COMPILE_TEST)
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	select REGMAP_MMIO
+	help
+	  Say Y or M if you want to add support for Atmel ASoc driver for boards
+	  using I2S.
 endif
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index 4440646..cd87cb4 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -3,10 +3,12 @@
 snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
 snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o
 snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
+snd-soc-atmel-i2s-objs := atmel-i2s.o
 
 obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
 obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
 obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
+obj-$(CONFIG_SND_ATMEL_SOC_I2S) += snd-soc-atmel-i2s.o
 
 # AT91 Machine Support
 snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c
new file mode 100644
index 0000000..5d3b5af
--- /dev/null
+++ b/sound/soc/atmel/atmel-i2s.c
@@ -0,0 +1,765 @@
+/*
+ * Driver for Atmel I2S controller
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ *
+ * Author: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#define ATMEL_I2SC_MAX_TDM_CHANNELS	8
+
+/*
+ * ---- I2S Controller Register map ----
+ */
+#define ATMEL_I2SC_CR		0x0000	/* Control Register */
+#define ATMEL_I2SC_MR		0x0004	/* Mode Register */
+#define ATMEL_I2SC_SR		0x0008	/* Status Register */
+#define ATMEL_I2SC_SCR		0x000c	/* Status Clear Register */
+#define ATMEL_I2SC_SSR		0x0010	/* Status Set Register */
+#define ATMEL_I2SC_IER		0x0014	/* Interrupt Enable Register */
+#define ATMEL_I2SC_IDR		0x0018	/* Interrupt Disable Register */
+#define ATMEL_I2SC_IMR		0x001c	/* Interrupt Mask Register */
+#define ATMEL_I2SC_RHR		0x0020	/* Receiver Holding Register */
+#define ATMEL_I2SC_THR		0x0024	/* Transmitter Holding Register */
+#define ATMEL_I2SC_VERSION	0x0028	/* Version Register */
+
+/*
+ * ---- Control Register (Write-only) ----
+ */
+#define ATMEL_I2SC_CR_RXEN	BIT(0)	/* Receiver Enable */
+#define ATMEL_I2SC_CR_RXDIS	BIT(1)	/* Receiver Disable */
+#define ATMEL_I2SC_CR_CKEN	BIT(2)	/* Clock Enable */
+#define ATMEL_I2SC_CR_CKDIS	BIT(3)	/* Clock Disable */
+#define ATMEL_I2SC_CR_TXEN	BIT(4)	/* Transmitter Enable */
+#define ATMEL_I2SC_CR_TXDIS	BIT(5)	/* Transmitter Disable */
+#define ATMEL_I2SC_CR_SWRST	BIT(7)	/* Software Reset */
+
+/*
+ * ---- Mode Register (Read/Write) ----
+ */
+#define ATMEL_I2SC_MR_MODE_MASK		GENMASK(0, 0)
+#define ATMEL_I2SC_MR_MODE_SLAVE	(0 << 0)
+#define ATMEL_I2SC_MR_MODE_MASTER	(1 << 0)
+
+#define ATMEL_I2SC_MR_DATALENGTH_MASK		GENMASK(4, 2)
+#define ATMEL_I2SC_MR_DATALENGTH_32_BITS	(0 << 2)
+#define ATMEL_I2SC_MR_DATALENGTH_24_BITS	(1 << 2)
+#define ATMEL_I2SC_MR_DATALENGTH_20_BITS	(2 << 2)
+#define ATMEL_I2SC_MR_DATALENGTH_18_BITS	(3 << 2)
+#define ATMEL_I2SC_MR_DATALENGTH_16_BITS	(4 << 2)
+#define ATMEL_I2SC_MR_DATALENGTH_16_BITS_COMPACT	(5 << 2)
+#define ATMEL_I2SC_MR_DATALENGTH_8_BITS		(6 << 2)
+#define ATMEL_I2SC_MR_DATALENGTH_8_BITS_COMPACT	(7 << 2)
+
+#define ATMEL_I2SC_MR_FORMAT_MASK	GENMASK(7, 6)
+#define ATMEL_I2SC_MR_FORMAT_I2S	(0 << 6)
+#define ATMEL_I2SC_MR_FORMAT_LJ		(1 << 6)  /* Left Justified */
+#define ATMEL_I2SC_MR_FORMAT_TDM	(2 << 6)
+#define ATMEL_I2SC_MR_FORMAT_TDMLJ	(3 << 6)
+
+/* Left audio samples duplicated to right audio channel */
+#define ATMEL_I2SC_MR_RXMONO		BIT(8)
+
+/* Receiver uses one DMA channel ... */
+#define ATMEL_I2SC_MR_RXDMA_MASK	GENMASK(9, 9)
+#define ATMEL_I2SC_MR_RXDMA_SINGLE	(0 << 9)  /* for all audio channels */
+#define ATMEL_I2SC_MR_RXDMA_MULTIPLE	(1 << 9)  /* per audio channel */
+
+/* I2SDO output of I2SC is internally connected to I2SDI input */
+#define ATMEL_I2SC_MR_RXLOOP		BIT(10)
+
+/* Left audio samples duplicated to right audio channel */
+#define ATMEL_I2SC_MR_TXMONO		BIT(12)
+
+/* Transmitter uses one DMA channel ... */
+#define ATMEL_I2SC_MR_TXDMA_MASK	GENMASK(13, 13)
+#define ATMEL_I2SC_MR_TXDMA_SINGLE	(0 << 13)  /* for all audio channels */
+#define ATMEL_I2SC_MR_TXDME_MULTIPLE	(1 << 13)  /* per audio channel */
+
+/* x sample transmitted when underrun */
+#define ATMEL_I2SC_MR_TXSAME_MASK	GENMASK(14, 14)
+#define ATMEL_I2SC_MR_TXSAME_ZERO	(0 << 14)  /* Zero sample */
+#define ATMEL_I2SC_MR_TXSAME_PREVIOUS	(1 << 14)  /* Previous sample */
+
+/* Audio Clock to I2SC Master Clock ratio */
+#define ATMEL_I2SC_MR_IMCKDIV_MASK	GENMASK(21, 16)
+#define ATMEL_I2SC_MR_IMCKDIV(div) \
+	(((div) << 16) & ATMEL_I2SC_MR_IMCKDIV_MASK)
+
+/* Master Clock to fs ratio */
+#define ATMEL_I2SC_MR_IMCKFS_MASK	GENMASK(29, 24)
+#define ATMEL_I2SC_MR_IMCKFS(fs) \
+	(((fs) << 24) & ATMEL_I2SC_MR_IMCKFS_MASK)
+
+/* Master Clock mode */
+#define ATMEL_I2SC_MR_IMCKMODE_MASK	GENMASK(30, 30)
+/* 0: No master clock generated (selected clock drives I2SCK pin) */
+#define ATMEL_I2SC_MR_IMCKMODE_I2SCK	(0 << 30)
+/* 1: master clock generated (internally generated clock drives I2SMCK pin) */
+#define ATMEL_I2SC_MR_IMCKMODE_I2SMCK	(1 << 30)
+
+/* Slot Width */
+/* 0: slot is 32 bits wide for DATALENGTH = 18/20/24 bits. */
+/* 1: slot is 24 bits wide for DATALENGTH = 18/20/24 bits. */
+#define ATMEL_I2SC_MR_IWS		BIT(31)
+
+/*
+ * ---- Status Registers ----
+ */
+#define ATMEL_I2SC_SR_RXEN	BIT(0)	/* Receiver Enabled */
+#define ATMEL_I2SC_SR_RXRDY	BIT(1)	/* Receive Ready */
+#define ATMEL_I2SC_SR_RXOR	BIT(2)	/* Receive Overrun */
+
+#define ATMEL_I2SC_SR_TXEN	BIT(4)	/* Transmitter Enabled */
+#define ATMEL_I2SC_SR_TXRDY	BIT(5)	/* Transmit Ready */
+#define ATMEL_I2SC_SR_TXUR	BIT(6)	/* Transmit Underrun */
+
+/* Receive Overrun Channel */
+#define ATMEL_I2SC_SR_RXORCH_MASK	GENMASK(15, 8)
+#define ATMEL_I2SC_SR_RXORCH(ch)	(1 << (((ch) & 0x7) + 8))
+
+/* Transmit Underrun Channel */
+#define ATMEL_I2SC_SR_TXURCH_MASK	GENMASK(27, 20)
+#define ATMEL_I2SC_SR_TXURCH(ch)	(1 << (((ch) & 0x7) + 20))
+
+/*
+ * ---- Interrupt Enable/Disable/Mask Registers ----
+ */
+#define ATMEL_I2SC_INT_RXRDY	ATMEL_I2SC_SR_RXRDY
+#define ATMEL_I2SC_INT_RXOR	ATMEL_I2SC_SR_RXOR
+#define ATMEL_I2SC_INT_TXRDY	ATMEL_I2SC_SR_TXRDY
+#define ATMEL_I2SC_INT_TXUR	ATMEL_I2SC_SR_TXUR
+
+static const struct regmap_config atmel_i2s_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = ATMEL_I2SC_VERSION,
+};
+
+struct atmel_i2s_gck_param {
+	int		fs;
+	unsigned long	mck;
+	int		imckdiv;
+	int		imckfs;
+};
+
+#define I2S_MCK_12M288		12288000UL
+#define I2S_MCK_11M2896		11289600UL
+
+/* mck = (32 * (imckfs+1) / (imckdiv+1)) * fs */
+static const struct atmel_i2s_gck_param gck_params[] = {
+	/* mck = 12.288MHz */
+	{  8000, I2S_MCK_12M288, 0, 47},	/* mck = 1536 fs */
+	{ 16000, I2S_MCK_12M288, 1, 47},	/* mck =  768 fs */
+	{ 24000, I2S_MCK_12M288, 3, 63},	/* mck =  512 fs */
+	{ 32000, I2S_MCK_12M288, 3, 47},	/* mck =  384 fs */
+	{ 48000, I2S_MCK_12M288, 7, 63},	/* mck =  256 fs */
+	{ 64000, I2S_MCK_12M288, 7, 47},	/* mck =  192 fs */
+	{ 96000, I2S_MCK_12M288, 7, 31},	/* mck =  128 fs */
+	{192000, I2S_MCK_12M288, 7, 15},	/* mck =   64 fs */
+
+	/* mck = 11.2896MHz */
+	{ 11025, I2S_MCK_11M2896, 1, 63},	/* mck = 1024 fs */
+	{ 22050, I2S_MCK_11M2896, 3, 63},	/* mck =  512 fs */
+	{ 44100, I2S_MCK_11M2896, 7, 63},	/* mck =  256 fs */
+	{ 88200, I2S_MCK_11M2896, 7, 31},	/* mck =  128 fs */
+	{176400, I2S_MCK_11M2896, 7, 15},	/* mck =   64 fs */
+};
+
+struct atmel_i2s_dev;
+
+struct atmel_i2s_caps {
+	int	(*mck_init)(struct atmel_i2s_dev *, struct device_node *np);
+};
+
+struct atmel_i2s_dev {
+	struct device				*dev;
+	struct regmap				*regmap;
+	struct clk				*pclk;
+	struct clk				*gclk;
+	struct clk				*aclk;
+	struct snd_dmaengine_dai_dma_data	playback;
+	struct snd_dmaengine_dai_dma_data	capture;
+	unsigned int				fmt;
+	const struct atmel_i2s_gck_param	*gck_param;
+	const struct atmel_i2s_caps		*caps;
+};
+
+static irqreturn_t atmel_i2s_interrupt(int irq, void *dev_id)
+{
+	struct atmel_i2s_dev *dev = dev_id;
+	unsigned int sr, imr, pending, ch, mask;
+	irqreturn_t ret = IRQ_NONE;
+
+	regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr);
+	regmap_read(dev->regmap, ATMEL_I2SC_IMR, &imr);
+	pending = sr & imr;
+
+	if (!pending)
+		return IRQ_NONE;
+
+	if (pending & ATMEL_I2SC_INT_RXOR) {
+		mask = ATMEL_I2SC_SR_RXOR;
+
+		for (ch = 0; ch < ATMEL_I2SC_MAX_TDM_CHANNELS; ++ch) {
+			if (sr & ATMEL_I2SC_SR_RXORCH(ch)) {
+				mask |= ATMEL_I2SC_SR_RXORCH(ch);
+				dev_err(dev->dev,
+					"RX overrun on channel %d\n", ch);
+			}
+		}
+		regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask);
+		ret = IRQ_HANDLED;
+	}
+
+	if (pending & ATMEL_I2SC_INT_TXUR) {
+		mask = ATMEL_I2SC_SR_TXUR;
+
+		for (ch = 0; ch < ATMEL_I2SC_MAX_TDM_CHANNELS; ++ch) {
+			if (sr & ATMEL_I2SC_SR_TXURCH(ch)) {
+				mask |= ATMEL_I2SC_SR_TXURCH(ch);
+				dev_err(dev->dev,
+					"TX underrun on channel %d\n", ch);
+			}
+		}
+		regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask);
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+#define ATMEL_I2S_RATES		SNDRV_PCM_RATE_8000_192000
+
+#define ATMEL_I2S_FORMATS	(SNDRV_PCM_FMTBIT_S8 |		\
+				 SNDRV_PCM_FMTBIT_S16_LE |	\
+				 SNDRV_PCM_FMTBIT_S18_3LE |	\
+				 SNDRV_PCM_FMTBIT_S20_3LE |	\
+				 SNDRV_PCM_FMTBIT_S24_3LE |	\
+				 SNDRV_PCM_FMTBIT_S24_LE |	\
+				 SNDRV_PCM_FMTBIT_S32_LE)
+
+static int atmel_i2s_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+	dev->fmt = fmt;
+	return 0;
+}
+
+static int atmel_i2s_prepare(struct snd_pcm_substream *substream,
+			     struct snd_soc_dai *dai)
+{
+	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+	bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+	unsigned int rhr, sr = 0;
+
+	if (is_playback) {
+		regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr);
+		if (sr & ATMEL_I2SC_SR_RXRDY) {
+			/*
+			 * The RX Ready flag should not be set. However if here,
+			 * we flush (read) the Receive Holding Register to start
+			 * from a clean state.
+			 */
+			dev_dbg(dev->dev, "RXRDY is set\n");
+			regmap_read(dev->regmap, ATMEL_I2SC_RHR, &rhr);
+		}
+	}
+
+	return 0;
+}
+
+static int atmel_i2s_get_gck_param(struct atmel_i2s_dev *dev, int fs)
+{
+	int i, best;
+
+	if (!dev->gclk || !dev->aclk) {
+		dev_err(dev->dev, "cannot generate the I2S Master Clock\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Find the best possible settings to generate the I2S Master Clock
+	 * from the PLL Audio.
+	 */
+	dev->gck_param = NULL;
+	best = INT_MAX;
+	for (i = 0; i < ARRAY_SIZE(gck_params); ++i) {
+		const struct atmel_i2s_gck_param *gck_param = &gck_params[i];
+		int val = abs(fs - gck_param->fs);
+
+		if (val < best) {
+			best = val;
+			dev->gck_param = gck_param;
+		}
+	}
+
+	return 0;
+}
+
+static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params,
+			       struct snd_soc_dai *dai)
+{
+	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+	bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+	unsigned int mr = 0;
+	int ret;
+
+	switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		mr |= ATMEL_I2SC_MR_FORMAT_I2S;
+		break;
+
+	default:
+		dev_err(dev->dev, "unsupported bus format\n");
+		return -EINVAL;
+	}
+
+	switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		/* codec is slave, so cpu is master */
+		mr |= ATMEL_I2SC_MR_MODE_MASTER;
+		ret = atmel_i2s_get_gck_param(dev, params_rate(params));
+		if (ret)
+			return ret;
+		break;
+
+	case SND_SOC_DAIFMT_CBM_CFM:
+		/* codec is master, so cpu is slave */
+		mr |= ATMEL_I2SC_MR_MODE_SLAVE;
+		dev->gck_param = NULL;
+		break;
+
+	default:
+		dev_err(dev->dev, "unsupported master/slave mode\n");
+		return -EINVAL;
+	}
+
+	switch (params_channels(params)) {
+	case 1:
+		if (is_playback)
+			mr |= ATMEL_I2SC_MR_TXMONO;
+		else
+			mr |= ATMEL_I2SC_MR_RXMONO;
+		break;
+	case 2:
+		break;
+	default:
+		dev_err(dev->dev, "unsupported number of audio channels\n");
+		return -EINVAL;
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S8:
+		mr |= ATMEL_I2SC_MR_DATALENGTH_8_BITS;
+		break;
+
+	case SNDRV_PCM_FORMAT_S16_LE:
+		mr |= ATMEL_I2SC_MR_DATALENGTH_16_BITS;
+		break;
+
+	case SNDRV_PCM_FORMAT_S18_3LE:
+		mr |= ATMEL_I2SC_MR_DATALENGTH_18_BITS | ATMEL_I2SC_MR_IWS;
+		break;
+
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		mr |= ATMEL_I2SC_MR_DATALENGTH_20_BITS | ATMEL_I2SC_MR_IWS;
+		break;
+
+	case SNDRV_PCM_FORMAT_S24_3LE:
+		mr |= ATMEL_I2SC_MR_DATALENGTH_24_BITS | ATMEL_I2SC_MR_IWS;
+		break;
+
+	case SNDRV_PCM_FORMAT_S24_LE:
+		mr |= ATMEL_I2SC_MR_DATALENGTH_24_BITS;
+		break;
+
+	case SNDRV_PCM_FORMAT_S32_LE:
+		mr |= ATMEL_I2SC_MR_DATALENGTH_32_BITS;
+		break;
+
+	default:
+		dev_err(dev->dev, "unsupported size/endianness for audio samples\n");
+		return -EINVAL;
+	}
+
+	return regmap_write(dev->regmap, ATMEL_I2SC_MR, mr);
+}
+
+static int atmel_i2s_switch_mck_generator(struct atmel_i2s_dev *dev,
+					  bool enabled)
+{
+	unsigned int mr, mr_mask;
+	unsigned long aclk_rate;
+	int ret;
+
+	mr = 0;
+	mr_mask = (ATMEL_I2SC_MR_IMCKDIV_MASK |
+		   ATMEL_I2SC_MR_IMCKFS_MASK |
+		   ATMEL_I2SC_MR_IMCKMODE_MASK);
+
+	if (!enabled) {
+		/* Disable the I2S Master Clock generator. */
+		ret = regmap_write(dev->regmap, ATMEL_I2SC_CR,
+				   ATMEL_I2SC_CR_CKDIS);
+		if (ret)
+			return ret;
+
+		/* Reset the I2S Master Clock generator settings. */
+		ret = regmap_update_bits(dev->regmap, ATMEL_I2SC_MR,
+					 mr_mask, mr);
+		if (ret)
+			return ret;
+
+		/* Disable/unprepare the PMC generated clock. */
+		clk_disable_unprepare(dev->gclk);
+
+		/* Disable/unprepare the PLL audio clock. */
+		clk_disable_unprepare(dev->aclk);
+		return 0;
+	}
+
+	if (!dev->gck_param)
+		return -EINVAL;
+
+	aclk_rate = dev->gck_param->mck * (dev->gck_param->imckdiv + 1);
+
+	/* Fist change the PLL audio clock frequency ... */
+	ret = clk_set_rate(dev->aclk, aclk_rate);
+	if (ret)
+		return ret;
+
+	/*
+	 * ... then set the PMC generated clock rate to the very same frequency
+	 * to set the gclk parent to aclk.
+	 */
+	ret = clk_set_rate(dev->gclk, aclk_rate);
+	if (ret)
+		return ret;
+
+	/* Prepare and enable the PLL audio clock first ... */
+	ret = clk_prepare_enable(dev->aclk);
+	if (ret)
+		return ret;
+
+	/* ... then prepare and enable the PMC generated clock. */
+	ret = clk_prepare_enable(dev->gclk);
+	if (ret)
+		return ret;
+
+	/* Update the Mode Register to generate the I2S Master Clock. */
+	mr |= ATMEL_I2SC_MR_IMCKDIV(dev->gck_param->imckdiv);
+	mr |= ATMEL_I2SC_MR_IMCKFS(dev->gck_param->imckfs);
+	mr |= ATMEL_I2SC_MR_IMCKMODE_I2SMCK;
+	ret = regmap_update_bits(dev->regmap, ATMEL_I2SC_MR, mr_mask, mr);
+	if (ret)
+		return ret;
+
+	/* Finally enable the I2S Master Clock generator. */
+	return regmap_write(dev->regmap, ATMEL_I2SC_CR,
+			    ATMEL_I2SC_CR_CKEN);
+}
+
+static int atmel_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+			     struct snd_soc_dai *dai)
+{
+	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+	bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+	bool is_master, mck_enabled;
+	unsigned int cr, mr;
+	int err;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		cr = is_playback ? ATMEL_I2SC_CR_TXEN : ATMEL_I2SC_CR_RXEN;
+		mck_enabled = true;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		cr = is_playback ? ATMEL_I2SC_CR_TXDIS : ATMEL_I2SC_CR_RXDIS;
+		mck_enabled = false;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Read the Mode Register to retrieve the master/slave state. */
+	err = regmap_read(dev->regmap, ATMEL_I2SC_MR, &mr);
+	if (err)
+		return err;
+	is_master = (mr & ATMEL_I2SC_MR_MODE_MASK) == ATMEL_I2SC_MR_MODE_MASTER;
+
+	/* If master starts, enable the audio clock. */
+	if (is_master && mck_enabled)
+		err = atmel_i2s_switch_mck_generator(dev, true);
+	if (err)
+		return err;
+
+	err = regmap_write(dev->regmap, ATMEL_I2SC_CR, cr);
+	if (err)
+		return err;
+
+	/* If master stops, disable the audio clock. */
+	if (is_master && !mck_enabled)
+		err = atmel_i2s_switch_mck_generator(dev, false);
+
+	return err;
+}
+
+static const struct snd_soc_dai_ops atmel_i2s_dai_ops = {
+	.prepare	= atmel_i2s_prepare,
+	.trigger	= atmel_i2s_trigger,
+	.hw_params	= atmel_i2s_hw_params,
+	.set_fmt	= atmel_i2s_set_dai_fmt,
+};
+
+static int atmel_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+	snd_soc_dai_init_dma_data(dai, &dev->playback, &dev->capture);
+	return 0;
+}
+
+static struct snd_soc_dai_driver atmel_i2s_dai = {
+	.probe	= atmel_i2s_dai_probe,
+	.playback = {
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = ATMEL_I2S_RATES,
+		.formats = ATMEL_I2S_FORMATS,
+	},
+	.capture = {
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = ATMEL_I2S_RATES,
+		.formats = ATMEL_I2S_FORMATS,
+	},
+	.ops = &atmel_i2s_dai_ops,
+	.symmetric_rates = 1,
+};
+
+static const struct snd_soc_component_driver atmel_i2s_component = {
+	.name	= "atmel-i2s",
+};
+
+static int atmel_i2s_sama5d2_mck_init(struct atmel_i2s_dev *dev,
+				      struct device_node *np)
+{
+	struct clk *muxclk;
+	int err;
+
+	if (!dev->gclk)
+		return 0;
+
+	/* muxclk is optional, so we return error for probe defer only */
+	muxclk = devm_clk_get(dev->dev, "muxclk");
+	if (IS_ERR(muxclk)) {
+		err = PTR_ERR(muxclk);
+		if (err == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		dev_warn(dev->dev,
+			 "failed to get the I2S clock control: %d\n", err);
+		return 0;
+	}
+
+	return clk_set_parent(muxclk, dev->gclk);
+}
+
+static const struct atmel_i2s_caps atmel_i2s_sama5d2_caps = {
+	.mck_init = atmel_i2s_sama5d2_mck_init,
+};
+
+static const struct of_device_id atmel_i2s_dt_ids[] = {
+	{
+		.compatible = "atmel,sama5d2-i2s",
+		.data = (void *)&atmel_i2s_sama5d2_caps,
+	},
+
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_i2s_dt_ids);
+
+static int atmel_i2s_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const struct of_device_id *match;
+	struct atmel_i2s_dev *dev;
+	struct resource *mem;
+	struct regmap *regmap;
+	void __iomem *base;
+	int irq;
+	int err = -ENXIO;
+	unsigned int pcm_flags = 0;
+	unsigned int version;
+
+	/* Get memory for driver data. */
+	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	/* Get hardware capabilities. */
+	match = of_match_node(atmel_i2s_dt_ids, np);
+	if (match)
+		dev->caps = match->data;
+
+	/* Map I/O registers. */
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	regmap = devm_regmap_init_mmio(&pdev->dev, base,
+				       &atmel_i2s_regmap_config);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	/* Request IRQ. */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	err = devm_request_irq(&pdev->dev, irq, atmel_i2s_interrupt, 0,
+			       dev_name(&pdev->dev), dev);
+	if (err)
+		return err;
+
+	/* Get the peripheral clock. */
+	dev->pclk = devm_clk_get(&pdev->dev, "pclk");
+	if (IS_ERR(dev->pclk)) {
+		err = PTR_ERR(dev->pclk);
+		dev_err(&pdev->dev,
+			"failed to get the peripheral clock: %d\n", err);
+		return err;
+	}
+
+	/* Get audio clocks to generate the I2S Master Clock (I2S_MCK) */
+	dev->aclk = devm_clk_get(&pdev->dev, "aclk");
+	dev->gclk = devm_clk_get(&pdev->dev, "gclk");
+	if (IS_ERR(dev->aclk) && IS_ERR(dev->gclk)) {
+		if (PTR_ERR(dev->aclk) == -EPROBE_DEFER ||
+		    PTR_ERR(dev->gclk) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		/* Master Mode not supported */
+		dev->aclk = NULL;
+		dev->gclk = NULL;
+	} else if (IS_ERR(dev->gclk)) {
+		err = PTR_ERR(dev->gclk);
+		dev_err(&pdev->dev,
+			"failed to get the PMC generated clock: %d\n", err);
+		return err;
+	} else if (IS_ERR(dev->aclk)) {
+		err = PTR_ERR(dev->aclk);
+		dev_err(&pdev->dev,
+			"failed to get the PLL audio clock: %d\n", err);
+		return err;
+	}
+
+	dev->dev = &pdev->dev;
+	dev->regmap = regmap;
+	platform_set_drvdata(pdev, dev);
+
+	/* Do hardware specific settings to initialize I2S_MCK generator */
+	if (dev->caps && dev->caps->mck_init) {
+		err = dev->caps->mck_init(dev, np);
+		if (err)
+			return err;
+	}
+
+	/* Enable the peripheral clock. */
+	err = clk_prepare_enable(dev->pclk);
+	if (err)
+		return err;
+
+	/* Get IP version. */
+	regmap_read(dev->regmap, ATMEL_I2SC_VERSION, &version);
+	dev_info(&pdev->dev, "hw version: %#x\n", version);
+
+	/* Enable error interrupts. */
+	regmap_write(dev->regmap, ATMEL_I2SC_IER,
+		     ATMEL_I2SC_INT_RXOR | ATMEL_I2SC_INT_TXUR);
+
+	err = devm_snd_soc_register_component(&pdev->dev,
+					      &atmel_i2s_component,
+					      &atmel_i2s_dai, 1);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register DAI: %d\n", err);
+		clk_disable_unprepare(dev->pclk);
+		return err;
+	}
+
+	/* Prepare DMA config. */
+	dev->playback.addr	= (dma_addr_t)mem->start + ATMEL_I2SC_THR;
+	dev->playback.maxburst	= 1;
+	dev->capture.addr	= (dma_addr_t)mem->start + ATMEL_I2SC_RHR;
+	dev->capture.maxburst	= 1;
+
+	if (of_property_match_string(np, "dma-names", "rx-tx") == 0)
+		pcm_flags |= SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX;
+	err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, pcm_flags);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register PCM: %d\n", err);
+		clk_disable_unprepare(dev->pclk);
+		return err;
+	}
+
+	return 0;
+}
+
+static int atmel_i2s_remove(struct platform_device *pdev)
+{
+	struct atmel_i2s_dev *dev = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(dev->pclk);
+
+	return 0;
+}
+
+static struct platform_driver atmel_i2s_driver = {
+	.driver		= {
+		.name	= "atmel_i2s",
+		.of_match_table	= of_match_ptr(atmel_i2s_dt_ids),
+	},
+	.probe		= atmel_i2s_probe,
+	.remove		= atmel_i2s_remove,
+};
+module_platform_driver(atmel_i2s_driver);
+
+MODULE_DESCRIPTION("Atmel I2S Controller driver");
+MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@atmel.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox