Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 07/14] ASoC: Add sun8i audio card
From: Thomas Petazzoni @ 2016-10-04 12:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <33d641ff43f0c0349cdfa2cdbbfdcdde66205596.1475571575.git.mylene.josserand@free-electrons.com>

Hello,

On Tue,  4 Oct 2016 11:46:20 +0200, Myl?ne Josserand wrote:

> +config SND_SUN8I
> +	tristate "Allwinner SUN6I/SUN8I audio card support"
> +	select SND_SUN8I_CODEC
> +	select SND_SUN4I_I2S
> +	select SND_SUN8I_CODEC_ANALOG
> +	select REGMAP_MMIO

I believe you need a:

	depends on OF

since you're unconditionally using some DT-related functionality in the
driver code.

> +#include <linux/firmware.h>

Do you really need this header file? I don't see anything
firmware-loading related in the driver.

> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +	struct snd_soc_dai_link *link = &sun8i_dai_link;
> +	struct device_node *np = pdev->dev.of_node;
> +	int ret;
> +
> +	/* register the soc card */
> +	sun8i_card.dev = &pdev->dev;
> +
> +	/* Retrieve the audio-codec from DT */
> +	link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);

Whenever you're using of_parse_phandle(), you must have a corresponding
of_node_put() to release the reference to the Device Tree node. So I
guess this should be done 1/ in the error path of ->probe(), and 2/
during the ->remove() hook.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH] dmaengine: coh901318: fix integer overflow when shifting more than 32 places
From: Linus Walleij @ 2016-10-04 12:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475172392.2027.12.camel@perches.com>

On Thu, Sep 29, 2016 at 8:06 PM, Joe Perches <joe@perches.com> wrote:
> On Thu, 2016-09-29 at 18:57 +0100, Colin King wrote:
>> Currently U300_DMA_CHANNELS is set to 40, meaning that the shift of 1 can
>> be more than 32 places, which leads to a 32 bit integer overflow. Fix this
>> by casting 1 to a u64 (the same type as started_channels) before shifting
>> it.
>
> trivia:
>
>> diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
> []
>> @@ -1353,7 +1353,7 @@ static ssize_t coh901318_debugfs_read(struct file *file, char __user *buf,
>>       tmp += sprintf(tmp, "DMA -- enabled dma channels\n");
>>
>>       for (i = 0; i < U300_DMA_CHANNELS; i++)
>> -             if (started_channels & (1 << i))
>> +             if (started_channels & ((u64)1 << i))
>
> Using
>
>                 if (started_channels & (1ULL << i))
>
> would be more common.

Even better (IMO):

#include <linux/bitops.h>

if (started_channels & BIT(i))

Apparently code is there to avoid the bit 31 problem, mea culpa.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
From: Code Kipper @ 2016-10-04 12:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2c5abe6578c8e4e841cb59357d88ce397551a593.1475571575.git.mylene.josserand@free-electrons.com>

On 4 October 2016 at 11:46, Myl?ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add APB deassert function for sun4i-i2s driver.
>
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 687a8f8..f3f7026 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/regmap.h>
> +#include <linux/reset.h>
>
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_params.h>
> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>         struct sun4i_i2s *i2s;
>         struct resource *res;
> +       struct reset_control *reset_apb;
>         void __iomem *regs;
>         int irq, ret;
>
> @@ -626,7 +628,19 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>                 dev_err(&pdev->dev, "Can't get our mod clock\n");
>                 return PTR_ERR(i2s->mod_clk);
>         }
> -
> +
> +       reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
> +       if (IS_ERR(reset_apb)) {
> +               dev_err(&pdev->dev, "Can't get apb reset\n");
> +               return PTR_ERR(i2s->mod_clk);
> +       }
> +
> +       ret = reset_control_deassert(reset_apb);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> +               return ret;
> +       }
> +
Is this functionality only required for A31 and onwards?,
CK
>         i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
>         i2s->playback_dma_data.maxburst = 4;
>
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
From: Thomas Petazzoni @ 2016-10-04 12:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2c5abe6578c8e4e841cb59357d88ce397551a593.1475571575.git.mylene.josserand@free-electrons.com>

Hello,

On Tue,  4 Oct 2016 11:46:16 +0200, Myl?ne Josserand wrote:

>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_params.h>
> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>  	struct sun4i_i2s *i2s;
>  	struct resource *res;
> +	struct reset_control *reset_apb;
>  	void __iomem *regs;
>  	int irq, ret;
>  
> @@ -626,7 +628,19 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  		dev_err(&pdev->dev, "Can't get our mod clock\n");
>  		return PTR_ERR(i2s->mod_clk);
>  	}
> -	
> +
> +	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");

I believe this is a change in the Device Tree binding, since you're
adding support for a new resource. Perhaps the Device Tree binding
documentation should be updated accordingly?

> +	if (IS_ERR(reset_apb)) {
> +		dev_err(&pdev->dev, "Can't get apb reset\n");
> +		return PTR_ERR(i2s->mod_clk);

This should be:

		return PTR_ERR(reset_apb);

> +	}
> +
> +	ret = reset_control_deassert(reset_apb);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> +		return ret;
> +	}

Do you need to re-assert the reset line in the ->remove() hook?

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* Coresight ETF trace dump failed in Juno r1 with 4.8-rc8
From: Venkatesh Vivekanandan @ 2016-10-04 12:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cc531f08-d09b-1976-90c2-377a5878b1eb@arm.com>

On Tue, Oct 4, 2016 at 4:00 PM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 04/10/16 06:37, Venkatesh Vivekanandan wrote:
>>
>> On Mon, Oct 3, 2016 at 6:44 PM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>>
>>> Hi Venkatesh,
>>>
>>> On 03/10/16 12:36, Venkatesh Vivekanandan wrote:
>>>>
>>>>
>>>> Hi All,
>>>>
>>>> I am trying to collect ETF trace from Juno R1 and could see "cpu
>>>> stall" while dumping the trace. Attached is the log of sequence
>>>> followed. Was trying to collect the trace data from hardware and see
>>>> if it is any valid data. Am I missing anything here?.
>>>>
>>>
>>> There are few fixes from me and Suzuki queued for v4.9.
>>> Can you check if this issue persists even on linux-next ?
>>
>>
>> Issue is the same in linux-next as well. Please find the attached log.
>>
>
> OK, what do you mean by the issue still being present. I no longer see
> any ETM failures or messages. Does the system hang when you try to read
> /dev/<addr>.etf ?
Yes, system hangs while reading /dev/<addr>.etf. Most of the times, it
gives RCU stall and sometimes just hangs and I have to reboot in both
case.
>
> Also the RCU stalls could be related to CPUIdle. Are you using latest
> versions of trusted firmware ?
Firmware is the one that came along with the board. Didn't update to
anything latest.

>From bootlog,

[    0.000000] Boot CPU: AArch64 Processor [411fd071]
[    0.000000] earlycon: pl11 at MMIO 0x000000007ff80000 (options '')
[    0.000000] bootconsole [pl11] enabled
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: EFI v2.50 by ARM Juno EFI Nov 24 2015 17:54:31
[    0.000000] efi:  ACPI=0xfe720000  ACPI 2.0=0xfe720014  PROP=0xfe773f30

Please let me know, if the firmware needs to be updated to specific
version. Any pointers on that would be appreciated.

>
> --
> Regards,
> Sudeep

^ permalink raw reply

* [PATCH 2/2] mfd: ab8500-debugfs: remove unused function
From: Linus Walleij @ 2016-10-04 12:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474695413-30460-1-git-send-email-baoyou.xie@linaro.org>

On Sat, Sep 24, 2016 at 7:36 AM, Baoyou Xie <baoyou.xie@linaro.org> wrote:

> We get 1 warning when building kernel with W=1:
> drivers/mfd/ab8500-debugfs.c:1395:6: warning: no previous prototype for 'ab8500_dump_all_banks_to_mem' [-Wmissing-prototypes]
>
> In fact, this function is called by no one and not exported,
> so this patch removes it.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8dfe0935d35b8a218ebf39d37113e27289a0de9b.1475571575.git.mylene.josserand@free-electrons.com>

Hello,

On Tue,  4 Oct 2016 11:46:15 +0200, Myl?ne Josserand wrote:
> Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.

There is no need to repeat the commit title inside the commit log
itself. What would be more useful is to explain *why* this is needed.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161004124011.d7f5754a082d5f17d5185fc4@free.fr>

Hello,

On Tue, 4 Oct 2016 12:40:11 +0200, Jean-Francois Moine wrote:

> > Add the case of a burst of 4 which is handled by the SoC.
> > 
> > Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> > ---
> >  drivers/dma/sun6i-dma.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 8346199..0485204 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > -- 
> > 2.9.3  
> 
> This patch has already been rejected by Maxime in the threads
> 	http://www.spinics.net/lists/dmaengine/msg08610.html
> and
> 	http://www.spinics.net/lists/dmaengine/msg08719.html
> 
> I hope you will find the way he wants for this maxburst to be added.

I was about to reply to Mylene's e-mail, suggesting that she should add
a comment in the code (and maybe in the commit log) to explain why this
addition is needed, and also that even though the schematics say that
value "1" (max burst size of 4 bytes) is reserved, it is in fact
incorrect. The Allwinner BSP code is really using this value, and it's
the value that makes audio work, so we believe the datasheet is simply
incorrect.

We already discussed it with Maxime, so I believe he should agree this
time. But I would suggest to have such details explained in the commit
log and in a comment in the code.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH v3 2/8] scpi: Add alternative legacy structures, functions and macros
From: Neil Armstrong @ 2016-10-04 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <da2f9471-4b54-c4cd-c3c2-de09fca52ab6@arm.com>

On 09/19/2016 05:24 PM, Sudeep Holla wrote:
> 
> 
> On 07/09/16 16:34, Neil Armstrong wrote:
>> In order to support the legacy SCPI protocol variant, add back the structures
>> and macros that varies against the final specification.
>> Add indirection table for legacy commands.
>> Add bitmap field for channel selection
>> Add support for legacy in scpi_send_message.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/firmware/arm_scpi.c | 218 ++++++++++++++++++++++++++++++++++++++++++--
>>  1 file changed, 211 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
>> index 9a87687..9ba1020 100644
>> --- a/drivers/firmware/arm_scpi.c
>> +++ b/drivers/firmware/arm_scpi.c
> 
> [..]
> 
>> @@ -336,6 +424,39 @@ static void scpi_handle_remote_msg(struct mbox_client *c, void *msg)
>>      scpi_process_cmd(ch, cmd);
>>  }
>>
>> +static void legacy_scpi_process_cmd(struct scpi_chan *ch)
>> +{
>> +    unsigned long flags;
>> +    struct scpi_xfer *t;
>> +
>> +    spin_lock_irqsave(&ch->rx_lock, flags);
>> +    if (list_empty(&ch->rx_pending)) {
>> +        spin_unlock_irqrestore(&ch->rx_lock, flags);
>> +        return;
>> +    }
>> +
>> +    t = list_first_entry(&ch->rx_pending, struct scpi_xfer, node);
>> +    list_del(&t->node);
>> +
> 
> This is a bad assumption that it will be always first. The legacy SCPI
> did support multiple commands at a time and they can be reordered when
> SCP responds to them. Except this it's almost same scpi_process_cmd. You
> should be able to use it as is if you pass the command.

I would be happy this was the case...

> 
>> +    /* check if wait_for_completion is in progress or timed-out */
>> +    if (t && !completion_done(&t->done)) {
>> +        struct legacy_scpi_shared_mem *mem = ch->rx_payload;
>> +        unsigned int len = t->rx_len;
>> +
>> +        t->status = le32_to_cpu(mem->status);
>> +        memcpy_fromio(t->rx_buf, mem->payload, len);
>> +        complete(&t->done);
>> +    }
>> +    spin_unlock_irqrestore(&ch->rx_lock, flags);
>> +}
>> +
>> +static void legacy_scpi_handle_remote_msg(struct mbox_client *c, void *_msg)
>> +{
>> +    struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
>> +
>> +    legacy_scpi_process_cmd(ch);
> 
> You will get the command in *_msg IIRC. So you can just pass that to
> scpi_process_cmd. You can even reuse scpi_handle_remote_msg

But Amlogic SCP firmware does not answer the command but only the first bit...
so we cannot queue commands because we cannot find back the queued command
from the replied MHU STAT value.

> 
> diff --git i/drivers/firmware/arm_scpi.c w/drivers/firmware/arm_scpi.c
> index edf1a3327041..165f2fc3b627 100644
> --- i/drivers/firmware/arm_scpi.c
> +++ w/drivers/firmware/arm_scpi.c
> @@ -419,7 +419,12 @@ static void scpi_handle_remote_msg(struct mbox_client *c, void *msg)
>  {
>         struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
>         struct scpi_shared_mem *mem = ch->rx_payload;
> -       u32 cmd = le32_to_cpu(mem->command);
> +       u32 cmd;
> +
> +       if (ch->is_legacy)
> +               cmd = *(u32 *)msg;
> +       else
> +               cmd = le32_to_cpu(mem->command);
> 
>         scpi_process_cmd(ch, cmd);
>  }
> 
>> +}
>> +
>>  static void scpi_tx_prepare(struct mbox_client *c, void *msg)
>>  {
>>      unsigned long flags;
>> @@ -356,6 +477,21 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg)
>>      mem->command = cpu_to_le32(t->cmd);
>>  }
>>
>> +static void legacy_scpi_tx_prepare(struct mbox_client *c, void *msg)
>> +{
>> +    unsigned long flags;
>> +    struct scpi_xfer *t = msg;
>> +    struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
>> +
>> +    if (t->tx_buf)
>> +        memcpy_toio(ch->tx_payload, t->tx_buf, t->tx_len);
>> +    if (t->rx_buf) {
>> +        spin_lock_irqsave(&ch->rx_lock, flags);
>> +        list_add_tail(&t->node, &ch->rx_pending);
>> +        spin_unlock_irqrestore(&ch->rx_lock, flags);
>> +    }
>> +}
> 
> Again here the only difference is token addition. I think we should
> retain that as it's helpful in debugging and I don't think it will have
> any issues. Worst case we can make it conditional but let's check if we
> can retain it first.

Yes token addition works.

> 
>> @@ -386,15 +522,25 @@ static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len,
>>      struct scpi_xfer *msg;
>>      struct scpi_chan *scpi_chan;
>>
>> -    chan = atomic_inc_return(&scpi_info->next_chan) % scpi_info->num_chans;
>> +    if (scpi_info->is_legacy)
>> +        chan = test_bit(cmd, scpi_info->cmd_priority) ? 1 : 0;
>> +    else
>> +        chan = atomic_inc_return(&scpi_info->next_chan) %
>> +            scpi_info->num_chans;
>>      scpi_chan = scpi_info->channels + chan;
>>
>>      msg = get_scpi_xfer(scpi_chan);
>>      if (!msg)
>>          return -ENOMEM;
>>
>> -    msg->slot = BIT(SCPI_SLOT);
>> -    msg->cmd = PACK_SCPI_CMD(cmd, tx_len);
>> +    if (scpi_info->is_legacy) {
>> +        mutex_lock(&scpi_chan->xfers_lock);
> 
> Why does legacy need a different locking scheme ?

Since we cannot queue, locking seems a really good idea...

> 
> [...]
> 
>> @@ -635,6 +804,24 @@ static int scpi_sensor_get_value(u16 sensor, u64 *val)
>>      return ret;
>>  }
>>
>> +static int legacy_scpi_sensor_get_value(u16 sensor, u64 *val)
>> +{
>> +    __le16 id = cpu_to_le16(sensor);
>> +    struct sensor_value buf;
>> +    int ret;
>> +
>> +    ret = check_cmd(CMD_SENSOR_VALUE);
>> +    if (ret)
>> +        return ret;
>> +
>> +    ret = scpi_send_message(scpi_info->scpi_cmds[CMD_SENSOR_VALUE],
>> +                &id, sizeof(id), &buf, sizeof(buf));
>> +    if (!ret)
>> +        *val = (u64)le32_to_cpu(buf.lo_val);
>> +
> 
> This is not needed as it's backward compatible as discussed before.
> Any particular reason you retained it here ?
> 

Sudeep,

I merged the commands as asked but Amlogic's SCP firmware only replies the value 1 in the MHU STAT registers.

This implies that :
 - We cannot distinguish what command ended in scpi_handle_remote_msg
 - We cannot find the last rx command in rx_pending list
 - We cannot read rx data length from the replied command
 - We cannot push multiple commands
 - We also need to wait for TX commands completion
 - We need locking in scpi_send_message around mbox_send_message and completion

I have an highly tweaked version with simplified path for legacy but with merged handle_remote_msg, tx_prepare and send_message functions
I will post shortly.

Neil

^ permalink raw reply

* PROBLEM: DWC3 USB 3.0 not working on Odroid-XU4 with Exynos 5422
From: Vivek Gautam @ 2016-10-04 12:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475578687.1912.28.camel@mniewoehner.de>

Hi Michael,


On Tue, Oct 4, 2016 at 4:28 PM, Michael Niew?hner <linux@mniewoehner.de> wrote:

> > > > > > [1.] One line summary of the problem:
> > > > > > DWC3 USB 3.0 not working on Odroid-XU4 with Exynos 5422
> > > > > >
> > > > > > [2.] Full description of the problem/report:
> > > > > > No usb 3.0 devices are being detected when attached while USB 2.0
> > > > > > devices work on the same port.
> > > > > > USB 3.0 works after applying patches [9.1] and [9.2], but seems
> > > > > > to be
> > > > > > buggy. The usb hub is redetected every time an usb device is
> > > > > > attached.

[snip]

>> > > > > > [9.] Other notes, patches, fixes, workarounds:
>> > > > > > [9.1] https://lkml.org/lkml/2014/4/28/234
>> > > > > > [9.2] https://lkml.org/lkml/2015/2/2/259
>>
>> These patches are required to get USB super-speed working on Exynos5420/5800.
>> But they did not make to upstream. There was resistance on adding new
>> phy_calibrate()
>> callback.
>>
>> Without these patches the Exynos5420/5800 will enumerate all
>> super-speed capable devices
>> as high-speed devices.
>> Last time we checked with exynos542x smdk boards and peach-* boards,
>> we could get the
>> Super - speed devices working. I have not tested odroid anytime so
>> don't have much idea about the
>> its intricacies.
>> I guess Anand was able to use these patches to get his kernel working in past.
>
>
> The patches don't work anymore with 4.8-rc* / 4.8. They worked - but very
> unstable - with 4.7.
>
> One more problem appeared since one of the 4.8-RCs: reboot hangs when the dwc3
> module is loaded. If I unload it before reboot / shutdown everything is fine.
>
>
>>
>> When you have a downstream on-board usb hub, ideally it should be able
>> to detect the devices
>> and not reset everytime you connect a new device (like you mentioned earlier).
>> There can be two possible reasons why the hub keeps getting reset ever
>> after applying the above
>> mentioned patches:
>> 1) the clock rates are not proper.
>> 2) the regulator load setting is not enough to drive the hub.
>>
>> Anand, can you please point Michael to an older kernel with which you
>> could test usb on odroid successfully ?
>> You can compare the clocks with an older version and see if there'a
>> any difference.
>>
>> Any possibility of any other framework (such as, bus-freq) trimming
>> down the clock - rates ?
>
>
> ################################
> # v4.7.5
> ################################
>
> $ cat /sys/kernel/debug/clk/clk_summary | grep usb
>  sclk_usbh20_scan_clk                     0            0   480000000          0
>  sclk_usbh20                              0            0    48000
> 000          0
>     mout_usbd300                          1            1    24000000          0
>        dout_usbd300                       0            0    24000000          0
>           sclk_usbd300
>                  0            0    24000000          0
>        dout_usbphy300                     1            1    24000000          0
>           sclk_usbphy300                  4            4    24000
> 000          0
>     mout_usbd301                          1            1    24000000          0
>        dout_usbd301                       0            0    24000000          0
>           sclk_usbd301
>                  0            0    24000000          0
>        dout_usbphy301                     1            1    24000000          0
>           sclk_usbphy301                  3            3    24000
> 000          0
>                          usbd301           1            1   100000000
>                          usbd300           1            1   100000000
>
> usbh20           3            3   100000000          0

>
> ################################
> # v4.8.0
> ################################
>
> $ cat /sys/kernel/debug/clk/clk_summary | grep usb
>  sclk_usbh20_scan_clk                     0            0   480000000          0
>  sclk_usbh20                              0            0    48000000
>         0
>     mout_usbd300                          1            1    24000000          0
>        dout_usbd300                       0            0    24000000          0
>           sclk_usbd300
>             0            0    24000000          0
>        dout_usbphy300                     1            1    24000000          0
>           sclk_usbphy300                  4            4    24000000
>         0
>     mout_usbd301                          1            1    24000000          0
>        dout_usbd301                       0            0    24000000          0
>           sclk_usbd301
>             0            0    24000000          0
>        dout_usbphy301                     1            1    24000000          0
>           sclk_usbphy301                  3            3    24000000
>         0
>                          usbd301           1            1   100000000

This clock should have been 200MHz.

>                          usbd300           1            1   100000000
>                          usbh2
> 0           3            3   100000000          0
>
> $ cat /sys/kernel/debug/usb/devices
> <<system hangs>>
>

The clocks are same across working/non-working.
Is it possible to bisect the commit that's causing hang for 4.8x ?

Adding few of the folks from Samsung who can test dwc3 usb on smdk/peach boards.
+Alim, Pankaj

Hi Alim, Pankaj,
can you please give a try with 4.8 kernel on peach/smdk542x board and
see if dwc3 usb works or not.
You may need to the patches mentioned in [9.1] and [9.2] mentioned above.


[snip]


Thanks
Vivek

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH V3 2/4] ARM64 LPC: LPC driver implementation on Hip06
From: John Garry @ 2016-10-04 12:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2af4f2d8-e3a4-fa00-e700-60af70bf4560@jonmasters.org>

On 02/10/2016 23:03, Jon Masters wrote:
> On 09/14/2016 02:32 PM, Arnd Bergmann wrote:
>> On Wednesday, September 14, 2016 10:50:44 PM CEST zhichang.yuan wrote:
>
>>> And there are probably multiple child devices under LPC, the global arm64_extio_ops only can cover one PIO range. It is fortunate only ipmi driver can not support I/O
>>> operation registering, serial driver has serial_in/serial_out to
>>> be registered. So, only the PIO range for ipmi device is stored
>>> in arm64_extio_ops and the indirect-IO
>>> works well for ipmi device.
>>
>> You should not do that in the serial driver, please just use the
>> normal 8250 driver that works fine once you handle the entire
>> port range.
>
> Just for the record, Arnd has the right idea. There is only one type of
> UART permitted by SBSA (PL011). We carved out an exception for a design
> that was already in flight and allowed it to be 16550. That other design
> was then corrected in future generations to be PL011 as we required it
> to be. Then there's the Hip06. I've given feedback elsewhere about the
> need for there to be (at most) two types of UART in the wild. This "LPC"
> stuff needs cleaning up (feedback given elsewhere already on that), but
> we won't be adding a third serial driver into the mix in order to make
> it work. There will be standard ARM servers. There will not be the
> kinda-sorta-standard. Thanks.
>

Right, so I think Zhichang can make the necessary generic changes to 
8250 OF driver to support IO port as well as MMIO-based.

However an LPC-based earlycon driver is still required.

A note on hip07-based D05 (for those unaware): this does not use 
LPC-based uart. It uses PL011. The hardware guys have managed some 
trickery where they loopback the serial line around the BMC/CPLD. But we 
still need it for hip06 D03 and any other boards which want to use LPC 
bus for uart.

A question on SBSA: does it propose how to provide serial via BMC for SOL?


> Jon.
>
>
> .
>

^ permalink raw reply

* [PATCH] bus: qcom-ebi2: depend on ARCH_QCOM or COMPILE_TEST
From: Linus Walleij @ 2016-10-04 11:56 UTC (permalink / raw)
  To: linux-arm-kernel

This hides the option for people who do not want their Kconfig
vision cluttered (i.e. x86) and enables compile testing apart
from the supported main arch.

Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ARM SoC people: please apply this to next/drivers as well
or as a fix depending on timing.
---
 drivers/bus/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 7010dcac9328..78751057164a 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -111,6 +111,7 @@ config OMAP_OCP2SCP
 config QCOM_EBI2
 	bool "Qualcomm External Bus Interface 2 (EBI2)"
 	depends on HAS_IOMEM
+	depends on ARCH_QCOM || COMPILE_TEST
 	help
 	  Say y here to enable support for the Qualcomm External Bus
 	  Interface 2, which can be used to connect things like NAND Flash,
-- 
2.7.4

^ permalink raw reply related

* [PATCH] ARM: dts: rockchip: Reserve unusable memory region on rk3066
From: Paweł Jarosz @ 2016-10-04 11:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2391111.dvDuarNnp9@phil>


>>>> I don't think this is a sane workaround, but it is at best difficult to
>>>> tell, given there's no reason given for why this memory is unusable.
>>>>
>>>> For instance, if bus accesses to this address hang, then this patch only
>>>> makes the hand less likely, since the kernel will still map the region
>>>> (and
>>>> therefore the CPU can perform speculative accesses).
>>>>
>>>> Are issues with this memory consistently seen in practice?
>>>>
>>>> Can you enable CONFIG_MEMTEST and pass 'memtest' to the kernel, to
>>>> determine if the memory is returning erroneous values?
>>> just for the sake of completeness, on the rk3288 the issue was the dma not
>>> being able to access the specific memory region (interestingly also the
>>> last 16MB but of the 4GB area supported on the rk3288). So memory itself
>>> was ok, just dma access to it failed.
>> How odd.
>>
>>> We didn't find any other sane solution to limit the dma access in a
>>> general way at the time, so opted for just blocking the memory region (as
>>> it was similarly only
>> I was under the impression that dma-ranges could describe this kind of
>> DMA addressing limitation. Was there some problem with that? Perhaps the
>> driver is not acquiring/configuring its mask correctly?
> I remember looking at (and trying) different options back then.
>
> dma-mask wanted power-of-2 values (so it's either 4GB or 2GB (or lower)),
> zone-dma was a 32bit (and non-dt) thing and dma-ranges seem to simply also
> calculate a dma-mask from the value, so you're down to 2GB again.
>
> So just blocking of those 16MB at the end for 4GB devices somehow sounded
> nicer than limiting dma access to only half the memory.
>
> I may be overlooking something but that was what I came up with last year.
>
>
> Heiko
Is there a chance to accept this patch?

I know it's not the best solution to this problem, but i don't know
a better one.

^ permalink raw reply

* [PATCH] net: axienet: Add missing \n to end of dev_err messages
From: Colin King @ 2016-10-04 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Colin Ian King <colin.king@canonical.com>

Trival fix, dev_err messages are missing a \n, so add it.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 69e2a83..35f9f97 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -818,7 +818,7 @@ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
 		goto out;
 	}
 	if (!(status & XAXIDMA_IRQ_ALL_MASK))
-		dev_err(&ndev->dev, "No interrupts asserted in Tx path");
+		dev_err(&ndev->dev, "No interrupts asserted in Tx path\n");
 	if (status & XAXIDMA_IRQ_ERROR_MASK) {
 		dev_err(&ndev->dev, "DMA Tx error 0x%x\n", status);
 		dev_err(&ndev->dev, "Current BD is at: 0x%x\n",
@@ -867,7 +867,7 @@ static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
 		goto out;
 	}
 	if (!(status & XAXIDMA_IRQ_ALL_MASK))
-		dev_err(&ndev->dev, "No interrupts asserted in Rx path");
+		dev_err(&ndev->dev, "No interrupts asserted in Rx path\n");
 	if (status & XAXIDMA_IRQ_ERROR_MASK) {
 		dev_err(&ndev->dev, "DMA Rx error 0x%x\n", status);
 		dev_err(&ndev->dev, "Current BD is at: 0x%x\n",
-- 
2.9.3

^ permalink raw reply related

* [PATCH 07/14] ASoC: Add sun8i audio card
From: Chen-Yu Tsai @ 2016-10-04 10:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAEKpxB=JLwqd_wKv1bUAifiQqVpX_RzXq6TSbjVWwza4LT6fhg@mail.gmail.com>

On Tue, Oct 4, 2016 at 6:16 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Myl?ne Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the audio card for sun8i SoC. This card links the codec driver
>> (digital part) with the DAI driver. The analog codec driver is
>> added as an aux_device.
>>
>> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  sound/soc/sunxi/Kconfig  |  14 +++++++
>>  sound/soc/sunxi/Makefile |   1 +
>>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 116 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index 9e287b0..7b97395 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>           A10 and affiliated SoCs.
>>
>> +config SND_SUN8I
>> +       tristate "Allwinner SUN6I/SUN8I audio card support"
>> +       select SND_SUN8I_CODEC
>> +       select SND_SUN4I_I2S
>> +       select SND_SUN8I_CODEC_ANALOG
>> +       select REGMAP_MMIO
>> +       help
>> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
>> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
>> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
>> +         (SND_SUN8I_CODEC_ANALOG).
>> +
>> +         Say Y or M if you want to add sun8i/6i card support
>> +
>>  config SND_SUN8I_CODEC
>>         tristate "Allwinner SUN8I audio codec"
>>         select REGMAP_MMIO
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 1da63d3..7f1bab9 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,5 +1,6 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
> Great work with this...I've been battling with the audio codec for the
> h3 for a while and it looks like almost everything that I need is
> delivered here.
>>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
>> new file mode 100644
>> index 0000000..565cd88
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i.c
>> @@ -0,0 +1,101 @@
>> +/*
>> + * ALSA SoC driver for Allwinner sun8i SoC
>> + *
>> + * Copyright (C) 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * 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.
>> + */
>> +
>> +#include <linux/firmware.h>
>> +#include <linux/module.h>
>> +
>> +#include <sound/soc.h>
>> +
>> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
>> +       {
>> +               .name = "sun8i-codec-analog",
>> +               .codec_name = "sun8i-codec-analog.0",
>> +       },
>> +};
>> +
>> +static struct snd_soc_dai_link sun8i_dai_link = {
>> +       .name           = "sun4i-i2s",
>> +       .stream_name    = "Playback",
>> +       .codec_dai_name = "sun8i",
>> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
>> +                       SND_SOC_DAIFMT_CBM_CFM,
>> +};
>> +
>> +static struct snd_soc_card sun8i_card = {
>> +       .name           = "sun8i-card",
>> +       .owner          = THIS_MODULE,
>> +       .dai_link       = &sun8i_dai_link,
>> +       .num_links      = 1,
>> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
>> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
>> +};
>> +
>> +static int sun8i_probe(struct platform_device *pdev)
>> +{
>> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
>> +       struct device_node *np = pdev->dev.of_node;
>> +       int ret;
>> +
>> +       /* register the soc card */
>> +       sun8i_card.dev = &pdev->dev;
>> +
>> +       /* Retrieve the audio-codec from DT */
>> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
>> +       if (!link->codec_of_node) {
>> +               dev_err(&pdev->dev, "Missing audio codec\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       /* Retrieve DAI from DT */
>> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
>> +       if (!link->cpu_of_node) {
>> +               dev_err(&pdev->dev, "Missing I2S controller\n");
>> +               return -EINVAL;
>> +       }
>> +
> My one question is that we have sun8i-a23 and sun8i-a33, and I think
> we need to distinguish them here. The sun8i-a23 doesn't use the i2s
> block but does use the prcm.

Agreed. Both the A23 and H3 follow the A31s, that is the codec is similar
to the A10/A31, but the analog controls are moved to the PRCM. We should
support these kinds with the existing codec driver.

ChenYu

>> +       link->platform_of_node = link->cpu_of_node;
>> +
>> +       /* Register the sound card */
>> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
>> +       if (ret) {
>> +               dev_err(&pdev->dev,
>> +                       "Soc register card failed %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static const struct of_device_id sun8i_of_match[] = {
>> +       { .compatible = "allwinner,sun8i-audio", },
>> +       {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
>> +
>> +static struct platform_driver sun8i_card_driver = {
>> +       .probe = sun8i_probe,
>> +       .driver = {
>> +               .name   = "sun8i-audio",
>> +               .of_match_table = sun8i_of_match,
>> +       },
>> +};
>> +
>> +module_platform_driver(sun8i_card_driver);
>> +
>> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
>> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 2.9.3
>>

^ permalink raw reply

* [PATCH v2] spi: spi-fsl-dspi: Add DMA support for Vybrid
From: Sanchayan Maity @ 2016-10-04 10:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8ccf4f2f4e6739410d9e242f9d0e3f3bcc76d0e2.1475498805.git.maitysanchayan@gmail.com>

Add DMA support for Vybrid.

Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
---
Changes since v1:
- Change in the dspi_dma_xfer function. Use more apt DSPI_FIFO_SIZE
instead of sizeof(u32)
- Do not set RSER on every iteration of loop

Tested on Toradex Colibri Vybrid VF61 module with spi based MCP CAN 251x
and spidev using RX/TX loopback and based on shawn's for-next branch
currently at 4.8-rc1.

Regards,
Sanchayan.
---
 drivers/spi/spi-fsl-dspi.c | 291 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 291 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 9e9dadb..0f81075 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
@@ -40,6 +42,7 @@
 #define TRAN_STATE_WORD_ODD_NUM	0x04
 
 #define DSPI_FIFO_SIZE			4
+#define DSPI_DMA_BUFSIZE		(DSPI_FIFO_SIZE * 1024)
 
 #define SPI_MCR		0x00
 #define SPI_MCR_MASTER		(1 << 31)
@@ -71,6 +74,11 @@
 #define SPI_SR_EOQF		0x10000000
 #define SPI_SR_TCFQF		0x80000000
 
+#define SPI_RSER_TFFFE		BIT(25)
+#define SPI_RSER_TFFFD		BIT(24)
+#define SPI_RSER_RFDFE		BIT(17)
+#define SPI_RSER_RFDFD		BIT(16)
+
 #define SPI_RSER		0x30
 #define SPI_RSER_EOQFE		0x10000000
 #define SPI_RSER_TCFQE		0x80000000
@@ -108,6 +116,8 @@
 
 #define SPI_TCR_TCNT_MAX	0x10000
 
+#define DMA_COMPLETION_TIMEOUT	msecs_to_jiffies(3000)
+
 struct chip_data {
 	u32 mcr_val;
 	u32 ctar_val;
@@ -117,6 +127,7 @@ struct chip_data {
 enum dspi_trans_mode {
 	DSPI_EOQ_MODE = 0,
 	DSPI_TCFQ_MODE,
+	DSPI_DMA_MODE,
 };
 
 struct fsl_dspi_devtype_data {
@@ -139,6 +150,22 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
 	.max_clock_factor = 8,
 };
 
+struct fsl_dspi_dma {
+	u32 curr_xfer_len;
+
+	u32 *tx_dma_buf;
+	struct dma_chan *chan_tx;
+	dma_addr_t tx_dma_phys;
+	struct completion cmd_tx_complete;
+	struct dma_async_tx_descriptor *tx_desc;
+
+	u32 *rx_dma_buf;
+	struct dma_chan *chan_rx;
+	dma_addr_t rx_dma_phys;
+	struct completion cmd_rx_complete;
+	struct dma_async_tx_descriptor *rx_desc;
+};
+
 struct fsl_dspi {
 	struct spi_master	*master;
 	struct platform_device	*pdev;
@@ -165,6 +192,7 @@ struct fsl_dspi {
 	u32			waitflags;
 
 	u32			spi_tcnt;
+	struct fsl_dspi_dma	*dma;
 };
 
 static inline int is_double_byte_mode(struct fsl_dspi *dspi)
@@ -368,6 +396,259 @@ static void dspi_tcfq_read(struct fsl_dspi *dspi)
 	dspi_data_from_popr(dspi, rx_word);
 }
 
+static void dspi_tx_dma_callback(void *arg)
+{
+	struct fsl_dspi *dspi = arg;
+	struct fsl_dspi_dma *dma = dspi->dma;
+
+	complete(&dma->cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+	struct fsl_dspi *dspi = arg;
+	struct fsl_dspi_dma *dma = dspi->dma;
+	int rx_word;
+	int i, len;
+	u16 d;
+
+	rx_word = is_double_byte_mode(dspi);
+
+	len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+	if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+		for (i = 0; i < len; i++) {
+			d = dspi->dma->rx_dma_buf[i];
+			rx_word ? (*(u16 *)dspi->rx = d) :
+						(*(u8 *)dspi->rx = d);
+			dspi->rx += rx_word + 1;
+		}
+	}
+
+	complete(&dma->cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+	struct fsl_dspi_dma *dma = dspi->dma;
+	struct device *dev = &dspi->pdev->dev;
+	int time_left;
+	int tx_word;
+	int i, len;
+	u16 val;
+
+	tx_word = is_double_byte_mode(dspi);
+
+	len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+	for (i = 0; i < len - 1; i++) {
+		val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+		dspi->dma->tx_dma_buf[i] =
+			SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
+			SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+		dspi->tx += tx_word + 1;
+	}
+
+	val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+	dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+					SPI_PUSHR_PCS(dspi->cs) |
+					SPI_PUSHR_CTAS(0);
+	dspi->tx += tx_word + 1;
+
+	dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
+					dma->tx_dma_phys,
+					DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!dma->tx_desc) {
+		dev_err(dev, "Not able to get desc for DMA xfer\n");
+		return -EIO;
+	}
+
+	dma->tx_desc->callback = dspi_tx_dma_callback;
+	dma->tx_desc->callback_param = dspi;
+	if (dma_submit_error(dmaengine_submit(dma->tx_desc))) {
+		dev_err(dev, "DMA submit failed\n");
+		return -EINVAL;
+	}
+
+	dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
+					dma->rx_dma_phys,
+					DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!dma->rx_desc) {
+		dev_err(dev, "Not able to get desc for DMA xfer\n");
+		return -EIO;
+	}
+
+	dma->rx_desc->callback = dspi_rx_dma_callback;
+	dma->rx_desc->callback_param = dspi;
+	if (dma_submit_error(dmaengine_submit(dma->rx_desc))) {
+		dev_err(dev, "DMA submit failed\n");
+		return -EINVAL;
+	}
+
+	reinit_completion(&dspi->dma->cmd_rx_complete);
+	reinit_completion(&dspi->dma->cmd_tx_complete);
+
+	dma_async_issue_pending(dma->chan_rx);
+	dma_async_issue_pending(dma->chan_tx);
+
+	time_left = wait_for_completion_timeout(&dspi->dma->cmd_tx_complete,
+					DMA_COMPLETION_TIMEOUT);
+	if (time_left == 0) {
+		dev_err(dev, "DMA tx timeout\n");
+		dmaengine_terminate_all(dma->chan_tx);
+		dmaengine_terminate_all(dma->chan_rx);
+		return -ETIMEDOUT;
+	}
+
+	time_left = wait_for_completion_timeout(&dspi->dma->cmd_rx_complete,
+					DMA_COMPLETION_TIMEOUT);
+	if (time_left == 0) {
+		dev_err(dev, "DMA rx timeout\n");
+		dmaengine_terminate_all(dma->chan_tx);
+		dmaengine_terminate_all(dma->chan_rx);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int dspi_dma_xfer(struct fsl_dspi *dspi)
+{
+	struct fsl_dspi_dma *dma = dspi->dma;
+	struct device *dev = &dspi->pdev->dev;
+	int curr_remaining_bytes;
+	int ret = 0;
+
+	curr_remaining_bytes = dspi->len;
+	while (curr_remaining_bytes) {
+		/* Check if current transfer fits the DMA buffer */
+		dma->curr_xfer_len = curr_remaining_bytes;
+		if (curr_remaining_bytes > DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE)
+			dma->curr_xfer_len = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
+
+		ret = dspi_next_xfer_dma_submit(dspi);
+		if (ret) {
+			dev_err(dev, "DMA transfer failed\n");
+			goto exit;
+
+		} else {
+			curr_remaining_bytes -= dma->curr_xfer_len;
+			if (curr_remaining_bytes < 0)
+				curr_remaining_bytes = 0;
+			dspi->len = curr_remaining_bytes;
+		}
+	}
+
+exit:
+	return ret;
+}
+
+static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
+{
+	struct fsl_dspi_dma *dma;
+	struct dma_slave_config cfg;
+	struct device *dev = &dspi->pdev->dev;
+	int ret;
+
+	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
+	if (!dma)
+		return -ENOMEM;
+
+	dma->chan_rx = dma_request_slave_channel(dev, "rx");
+	if (!dma->chan_rx) {
+		dev_err(dev, "rx dma channel not available\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	dma->chan_tx = dma_request_slave_channel(dev, "tx");
+	if (!dma->chan_tx) {
+		dev_err(dev, "tx dma channel not available\n");
+		ret = -ENODEV;
+		goto err_tx_channel;
+	}
+
+	dma->tx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
+					&dma->tx_dma_phys, GFP_KERNEL);
+	if (!dma->tx_dma_buf) {
+		ret = -ENOMEM;
+		goto err_tx_dma_buf;
+	}
+
+	dma->rx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
+					&dma->rx_dma_phys, GFP_KERNEL);
+	if (!dma->rx_dma_buf) {
+		ret = -ENOMEM;
+		goto err_rx_dma_buf;
+	}
+
+	cfg.src_addr = phy_addr + SPI_POPR;
+	cfg.dst_addr = phy_addr + SPI_PUSHR;
+	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.src_maxburst = 1;
+	cfg.dst_maxburst = 1;
+
+	cfg.direction = DMA_DEV_TO_MEM;
+	ret = dmaengine_slave_config(dma->chan_rx, &cfg);
+	if (ret) {
+		dev_err(dev, "can't configure rx dma channel\n");
+		ret = -EINVAL;
+		goto err_slave_config;
+	}
+
+	cfg.direction = DMA_MEM_TO_DEV;
+	ret = dmaengine_slave_config(dma->chan_tx, &cfg);
+	if (ret) {
+		dev_err(dev, "can't configure tx dma channel\n");
+		ret = -EINVAL;
+		goto err_slave_config;
+	}
+
+	dspi->dma = dma;
+	dspi->devtype_data->trans_mode = DSPI_DMA_MODE;
+	init_completion(&dma->cmd_tx_complete);
+	init_completion(&dma->cmd_rx_complete);
+
+	return 0;
+
+err_slave_config:
+	devm_kfree(dev, dma->rx_dma_buf);
+err_rx_dma_buf:
+	devm_kfree(dev, dma->tx_dma_buf);
+err_tx_dma_buf:
+	dma_release_channel(dma->chan_tx);
+err_tx_channel:
+	dma_release_channel(dma->chan_rx);
+
+	devm_kfree(dev, dma);
+	dspi->dma = NULL;
+
+	return ret;
+}
+
+static void dspi_release_dma(struct fsl_dspi *dspi)
+{
+	struct fsl_dspi_dma *dma = dspi->dma;
+	struct device *dev = &dspi->pdev->dev;
+
+	if (dma) {
+		if (dma->chan_tx) {
+			dma_unmap_single(dev, dma->tx_dma_phys,
+					DSPI_DMA_BUFSIZE, DMA_TO_DEVICE);
+			dma_release_channel(dma->chan_tx);
+		}
+
+		if (dma->chan_rx) {
+			dma_unmap_single(dev, dma->rx_dma_phys,
+					DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE);
+			dma_release_channel(dma->chan_rx);
+		}
+	}
+}
+
 static int dspi_transfer_one_message(struct spi_master *master,
 		struct spi_message *message)
 {
@@ -424,6 +705,12 @@ static int dspi_transfer_one_message(struct spi_master *master,
 			regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE);
 			dspi_tcfq_write(dspi);
 			break;
+		case DSPI_DMA_MODE:
+			regmap_write(dspi->regmap, SPI_RSER,
+				SPI_RSER_TFFFE | SPI_RSER_TFFFD |
+				SPI_RSER_RFDFE | SPI_RSER_RFDFD);
+			status = dspi_dma_xfer(dspi);
+			goto out;
 		default:
 			dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n",
 				trans_mode);
@@ -730,6 +1017,9 @@ static int dspi_probe(struct platform_device *pdev)
 	}
 	clk_prepare_enable(dspi->clk);
 
+	if (dspi_request_dma(dspi, res->start))
+		dev_warn(&pdev->dev, "can't get dma channels\n");
+
 	master->max_speed_hz =
 		clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor;
 
@@ -758,6 +1048,7 @@ static int dspi_remove(struct platform_device *pdev)
 	struct fsl_dspi *dspi = spi_master_get_devdata(master);
 
 	/* Disconnect from the SPI framework */
+	dspi_release_dma(dspi);
 	clk_disable_unprepare(dspi->clk);
 	spi_unregister_master(dspi->master);
 	spi_master_put(dspi->master);
-- 
2.10.0

^ permalink raw reply related

* [PATCH 04/14] ASoC: Add sun8i analog codec driver
From: Chen-Yu Tsai @ 2016-10-04 10:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAEKpxBk-e-sXXWD7p6Db_EsFP1bTVjeFsroy7+r5V-ZYC4ndmg@mail.gmail.com>

On Tue, Oct 4, 2016 at 6:21 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Myl?ne Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the analog part of the sun8i (A33) codec driver. This driver
>> implements all the analog part of the codec using PRCM registers.
>>
>> The read/write regmap functions must be handled in a custom way as
>> the PRCM register behaves as "mailbox" register.
>>
>> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  sound/soc/sunxi/Kconfig              |   7 +
>>  sound/soc/sunxi/Makefile             |   1 +
>>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
>>  3 files changed, 312 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index dd23682..7aee95a 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>>         help
>>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>           A10 and affiliated SoCs.
>> +
>> +config SND_SUN8I_CODEC_ANALOG
>> +       tristate "Allwinner SUN8I analog codec"
>> +       select REGMAP_MMIO
>> +        help
>> +         Say Y or M if you want to add sun8i analog audiocodec support
>> +
>>  endmenu
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 604c7b84..241c0df 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,3 +1,4 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
>> new file mode 100644
>> index 0000000..be3d540
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
>> @@ -0,0 +1,304 @@
>> +/*
>> + * This driver supports the analog controls for the internal codec
>> + * found in Allwinner's A31s, A33 and A23 SoCs.
>> + *
>> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
>> + * Copyright 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * 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.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/io.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +
>> +#include <sound/soc.h>
>> +#include <sound/soc-dapm.h>
>> +#include <sound/tlv.h>
>> +
>> +/* Codec analog control register offsets and bit fields */
>> +#define SUN8I_ADDA_HP_VOLC                             0x00
>> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
>> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
>> +#define SUN8I_ADDA_LOMIXSC                             0x01
>> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
>> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
>> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
>> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
>> +#define SUN8I_ADDA_ROMIXSC                             0x02
>> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
>> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
>> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
>> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
>> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
>> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
>> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
>> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
>> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
>> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
>> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
>> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
>> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
>> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
>> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
>> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
>> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
>> +
>> +/* Analog control register access bits */
>> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 */
>> +#define ADDA_PR_RESET                          BIT(28)
>> +#define ADDA_PR_WRITE                          BIT(24)
>> +#define ADDA_PR_ADDR_SHIFT                     16
>> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
>> +#define ADDA_PR_DATA_IN_SHIFT                  8
>> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
>> +#define ADDA_PR_DATA_OUT_SHIFT                 0
>> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
>> +
>> +/* regmap access bits */
>> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
>> +{
>> +       void __iomem *base = context;
>> +       u32 tmp;
>> +
>> +       tmp = readl(base);
>> +
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
>> +
>> +       return 0;
>> +}
>> +
>> +static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
>> +{
>> +       void __iomem *base = context;
>> +       u32 tmp;
>> +
>> +       tmp = readl(base);
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       /* Write the address */
>> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Write the value */
>> +       tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
>> +       tmp |= val << ADDA_PR_DATA_IN_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Indicate that the previous value must be written */
>> +       writel(readl(base) | ADDA_PR_WRITE, base);
>> +
>> +       /* Reset the write bit */
>> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
>> +
>> +       return 0;
>> +}
>> +
>> +struct regmap_config adda_pr_regmap_cfg = {
>> +       .name           = "adda-pr",
>> +       .reg_bits       = 5,
>> +       .reg_stride     = 1,
>> +       .val_bits       = 8,
>> +       .reg_read       = adda_reg_read,
>> +       .reg_write      = adda_reg_write,
>> +       .fast_io        = true,
>> +       .max_register   = 24,
>> +};
>> +
>> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
>> +
>> +static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
>> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
>> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
>> +                      sun8i_codec_headphone_volume_scale),
>> +
>> +       /* Playback Switch */
>> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
>> +                  1, 0),
>> +
>> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
>> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
>> +};
>> +
>> +/* headphone controls */
>> +static const char * const sun8i_codec_hp_src_enum_text[] = {
>> +       "DAC", "Mixer",
>> +};
>> +
>> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
>> +                           SUN8I_ADDA_DAC_PA_SRC,
>> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
>> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
>> +                           sun8i_codec_hp_src_enum_text);
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
>> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
>> +                     sun8i_codec_hp_src_enum),
>> +};
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
>> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
>> +};
>> +
>> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
>> +       /* Mixers */
>> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +
>> +       /* Headphone output path */
>> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
>> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
>> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
>> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
>> +
>> +       /* Headphone outputs */
>> +       SND_SOC_DAPM_OUTPUT("HP"),
>> +
>> +};
>> +
>> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
>> +       /* Left Mixer Routes */
>> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
>> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
>> +
>> +       /* Right Mixer Routes */
>> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
>> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
>> +
>> +       /* Headphone Routes */
>> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
>> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
>> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
>> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
>> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
>> +       { "HP", NULL, "Headphone Amp" },
>> +};
>> +
>> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
>> +       .name                   = "sun8i-codec-analog",
>> +       .controls               = sun8i_analog_widgets,
>> +       .num_controls           = ARRAY_SIZE(sun8i_analog_widgets),
>> +       .dapm_widgets           = sun8i_codec_analog_dapm_widgets,
>> +       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
>> +       .dapm_routes            = sun8i_codec_analog_dapm_routes,
>> +       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
>> +};
>> +
>> +static const struct of_device_id sun8i_codec_analog_of_match[] = {
>> +       { .compatible = "allwinner,sun8i-codec-analog", },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
>> +
>> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
>> +{
>> +       struct resource *res;
>> +       struct regmap *regmap;
>> +       void __iomem *base;
>> +
>> +       /* Get PRCM resources and registers */
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       base = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(base)) {
>> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
>> +               return PTR_ERR(base);
>> +       }
>> +
>> +       regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
>> +       if (IS_ERR(regmap)) {
>> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
>> +               return PTR_ERR(regmap);
>> +       }
>> +
>> +       return devm_snd_soc_register_component(&pdev->dev,
>> +                                              &sun8i_codec_analog_cmpnt_drv,
>> +                                              NULL, 0);
>> +}
>> +
>> +static struct platform_driver sun8i_codec_analog_driver = {
>> +       .driver = {
>> +               .name = "sun8i-codec-analog",
>> +               .of_match_table = sun8i_codec_analog_of_match,
>> +       },
>> +       .probe = sun8i_codec_analog_probe,
>> +};
>> +module_platform_driver(sun8i_codec_analog_driver);
>> +
>> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
> Does the A31s have the prcm for the codec?, as I was under the
> impression that it was the same as the A31 and I can't seem to find a
> datasheet for that SoC. You could also add H3 and A64 here.

Yes it does, which is why I made this driver.

You can find the datasheet for the A31s in Allwinner's Github repo:

    https://github.com/allwinner-zh/documents

ChenYu

> CK
>> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
>> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:sun8i-codec-analog");
>> --
>> 2.9.3
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v26 0/7] arm64: add kdump support
From: James Morse @ 2016-10-04 10:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <691230c7-051d-afee-9014-d22963a8f045@caviumnetworks.com>

Hi Manish,

On 04/10/16 11:05, Manish Jaggi wrote:
> On 10/04/2016 03:16 PM, James Morse wrote:
>> On 03/10/16 13:41, Manish Jaggi wrote:
>>> On 10/03/2016 04:34 PM, AKASHI Takahiro wrote:
>>>> On Mon, Oct 03, 2016 at 01:24:34PM +0530, Manish Jaggi wrote:
>>>>> First kernel is booted with mem=2G crashkernel=1G command line option.
>>>>> While the system has 64G memory.
>>
>>>> Are you saying that "mem=..." doesn't have any effect?
>>> What I am saying it that If the first kernel is booted using mem= option and crashkernel= option
>>> the memory for second kernel has to be withing the crashkernel size.
>>> As per /proc/iomem System RAM the information is correct, but the /proc/meminfo is showing total memory
>>> much more than the first kernel had in first place.
>>
>> So your second crashkernel has 63G of memory? Unless you provide the same 'mem='
>> to the kdump kernel, this is the expected behaviour. The
>> DT:/reserved-memory/crash_dump describes the memory not to use.
>>
>> On your first boot with 'mem=2G' memblock_mem_limit_remove_map() called from
>> arm64_memblock_init() removed the top 62G of memory. Neither the first kernel
>> nor kexec-tools know about the top 62G.
>> When you run kexec-tools, it describes what it sees in /proc/iomem in the
>> DT:/reserved-memory/crash_dump, which is just the remaining 1G of memory.
>>
>> When we crash and reboot, the crash kernel discovers all 64G of memory from the
>> EFI memory map.

> So the iomem and meminfo should be same or different for the second kernel?
> Also i assumed that crashkernel=1G should restrict the second kernels to 1G.

Not with v26 of this series. What should it do with the 62G of memory that was
removed by booting with 'mem=2G'? It isn't part of the crashkernel reserved
area, and it isn't part of the vmcore described in elfcorehdr either...


> This is my understanding from the description. It should not require a second mem= option

>> kexec-tools described the 1G of memory that the first kernel was using in the
>> DT:/reserved-memory/crash_dump node, so early_init_fdt_scan_reserved_mem()
>> reserves the 1G of memory the first kernel used. This leaves us with 63G of memory.
>>
>> This may change with the next version of kdump if it switches back to using
>> DT:/chosen/linux,usable-memory-range.
>> If you need v26 to avoid the top 62G of memory, you need to provide the same
>> 'mem=' to the first and second kernel.

> If I provide for second kernel, I dont see any prints after Bye.
> Have you tired this anytime?

Yes, on juno-r1 passing 'mem=2G' to both the first and second kernel causes only
the first 2G of memory to be used with this pattern:
first kernel:		[1G used for linux]	[1G reserved for Crash kernel] 	[6G memory
hidden]
kdump kernel:	[1G vmcore]			[1G used for linux] 			[6G memory hidden]


>>>>> 1.2 Live crash dump fails with error
>>
>> ... do we expect this to work? I don't think it has anything to do with this
>> series...
>>
> Why it should not?
> I saved the vmcore file while in second kernel. Since crash without vmcore file didnt run,
> Tried with vmcore file and it worked. Its just that if you want to boot a second kernel
>  with read only file system without network live crash dump analysis is handy.

Ah, you want to run /usr/bin/crash with the kdump boot of linux. You still need
to tell it where to find the memory image: "crash /path/to/vmlinux /proc/vmcore"
should do the trick.


Thanks,

James

^ permalink raw reply

* [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
From: Jean-Francois Moine @ 2016-10-04 10:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c74aea452bd1831f439dd67884cb2879e0849f03.1475571575.git.mylene.josserand@free-electrons.com>

On Tue,  4 Oct 2016 11:46:18 +0200
Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:

> The sun8i audio codec is using PRCM registers to configure all the
> analog part of the audio codec. It is added as a subnode of the PRCM
> with his resource (offset of 0x1c0).
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
	[snip]

I was heard that the PRCM as a MFD would disappear.

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
From: Jean-Francois Moine @ 2016-10-04 10:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3a2404510b5f8b16ae3bb193982d70f158700b2b.1475571575.git.mylene.josserand@free-electrons.com>

On Tue,  4 Oct 2016 11:46:14 +0200
Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:

> Add the case of a burst of 4 which is handled by the SoC.
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/dma/sun6i-dma.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 8346199..0485204 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>  	switch (maxburst) {
>  	case 1:
>  		return 0;
> +	case 4:
> +		return 1;
>  	case 8:
>  		return 2;
>  	default:
> -- 
> 2.9.3

This patch has already been rejected by Maxime in the threads
	http://www.spinics.net/lists/dmaengine/msg08610.html
and
	http://www.spinics.net/lists/dmaengine/msg08719.html

I hope you will find the way he wants for this maxburst to be added.

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply

* [PATCH] efi/arm: fix absolute relocation detection for older toolchains
From: Ard Biesheuvel @ 2016-10-04 10:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161003205233.GO16071@codeblueprint.co.uk>

On 3 October 2016 at 13:52, Matt Fleming <matt@codeblueprint.co.uk> wrote:
> On Fri, 30 Sep, at 04:01:55PM, Ard Biesheuvel wrote:
>>
>> This is a workaround for now. We can revisit this when a need arises to copy
>> more kernel code into the stub, by which time we could put in a more elaborate
>> fix, or decide to no longer care about 'older' versions of objcopy.
>>
>> Since this fixes an ARM specific issue and only affects ARM specific Makefile
>> variables, I am happy for this to go on top of the arm-soc patch that enables
>> CONFIG_EFI for ARM's multi_v7_defconfig (queued for v4.9), given that we have
>> no other changes queued in linux-efi that should conflict with this patch.
>>
>> Matt, any concerns?
>
> Not with the patch, but could we clarify the user-visible effects of
> not applying it? Are the absolute relocations harmless, or will they
> lead to crashes?

These relocations are harmless, since the debug ones are only
interpreted by the debugger, and the ones generated by
EXPORT_SYMBOL(sort) will never be referenced, since the symbols they
contain are either renamed to __efistub_xxx (arm64), or they are not
part of the kernel proper (arm)

So both cases are false positives, but the diagnostic is important,
and so breaking the build is appropriate for any other absolute
relocation that may appear.

The effect of the patch is not that the diagnostic is ignored, but
that these relocations are not generated in the first place (-g0) or
removed explicitly (ksymtab/krcrctab+sort) rather than via a wildcard.
So other than not breaking the build, this patch should have no user
observeable differences.

-- 
Ard.

^ permalink raw reply

* [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
From: Mark Brown @ 2016-10-04 10:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <06ea14939405c3eb0fb9be655d26ee564a04a53d.1475571575.git.mylene.josserand@free-electrons.com>

On Tue, Oct 04, 2016 at 11:46:21AM +0200, Myl?ne Josserand wrote:

> +* Allwinner A23/A33 Analog Codec
> +
> +This codec must be handled as a PRCM subnode.

What does this mean - how does one handle something as a "PRCM subnode"?

Please use subject lines matching the style for the subsystem.  This
makes it easier for people to identify relevant patches.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/c28f6542/attachment.sig>

^ permalink raw reply

* Coresight ETF trace dump failed in Juno r1 with 4.8-rc8
From: Sudeep Holla @ 2016-10-04 10:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGhh56H7a9oEYxzEA4gGvBey=COMqwgisd4tzewU8DLGcGrsww@mail.gmail.com>



On 04/10/16 06:37, Venkatesh Vivekanandan wrote:
> On Mon, Oct 3, 2016 at 6:44 PM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>> Hi Venkatesh,
>>
>> On 03/10/16 12:36, Venkatesh Vivekanandan wrote:
>>>
>>> Hi All,
>>>
>>> I am trying to collect ETF trace from Juno R1 and could see "cpu
>>> stall" while dumping the trace. Attached is the log of sequence
>>> followed. Was trying to collect the trace data from hardware and see
>>> if it is any valid data. Am I missing anything here?.
>>>
>>
>> There are few fixes from me and Suzuki queued for v4.9.
>> Can you check if this issue persists even on linux-next ?
>
> Issue is the same in linux-next as well. Please find the attached log.
>

OK, what do you mean by the issue still being present. I no longer see
any ETM failures or messages. Does the system hang when you try to read
/dev/<addr>.etf ?

Also the RCU stalls could be related to CPUIdle. Are you using latest
versions of trusted firmware ?

-- 
Regards,
Sudeep

^ permalink raw reply

* [PATCH 04/14] ASoC: Add sun8i analog codec driver
From: Code Kipper @ 2016-10-04 10:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <db0f628732e8b52b36b8204f146573926957e654.1475571575.git.mylene.josserand@free-electrons.com>

On 4 October 2016 at 11:46, Myl?ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the analog part of the sun8i (A33) codec driver. This driver
> implements all the analog part of the codec using PRCM registers.
>
> The read/write regmap functions must be handled in a custom way as
> the PRCM register behaves as "mailbox" register.
>
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/Kconfig              |   7 +
>  sound/soc/sunxi/Makefile             |   1 +
>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
>  3 files changed, 312 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index dd23682..7aee95a 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>         help
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
> +
> +config SND_SUN8I_CODEC_ANALOG
> +       tristate "Allwinner SUN8I analog codec"
> +       select REGMAP_MMIO
> +        help
> +         Say Y or M if you want to add sun8i analog audiocodec support
> +
>  endmenu
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 604c7b84..241c0df 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,3 +1,4 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
> new file mode 100644
> index 0000000..be3d540
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
> @@ -0,0 +1,304 @@
> +/*
> + * This driver supports the analog controls for the internal codec
> + * found in Allwinner's A31s, A33 and A23 SoCs.
> + *
> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
> + * Copyright 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * 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.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <sound/soc.h>
> +#include <sound/soc-dapm.h>
> +#include <sound/tlv.h>
> +
> +/* Codec analog control register offsets and bit fields */
> +#define SUN8I_ADDA_HP_VOLC                             0x00
> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
> +#define SUN8I_ADDA_LOMIXSC                             0x01
> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
> +#define SUN8I_ADDA_ROMIXSC                             0x02
> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
> +
> +/* Analog control register access bits */
> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 */
> +#define ADDA_PR_RESET                          BIT(28)
> +#define ADDA_PR_WRITE                          BIT(24)
> +#define ADDA_PR_ADDR_SHIFT                     16
> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
> +#define ADDA_PR_DATA_IN_SHIFT                  8
> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
> +#define ADDA_PR_DATA_OUT_SHIFT                 0
> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
> +
> +/* regmap access bits */
> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
> +{
> +       void __iomem *base = context;
> +       u32 tmp;
> +
> +       tmp = readl(base);
> +
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
> +
> +       return 0;
> +}
> +
> +static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
> +{
> +       void __iomem *base = context;
> +       u32 tmp;
> +
> +       tmp = readl(base);
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       /* Write the address */
> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Write the value */
> +       tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
> +       tmp |= val << ADDA_PR_DATA_IN_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Indicate that the previous value must be written */
> +       writel(readl(base) | ADDA_PR_WRITE, base);
> +
> +       /* Reset the write bit */
> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
> +
> +       return 0;
> +}
> +
> +struct regmap_config adda_pr_regmap_cfg = {
> +       .name           = "adda-pr",
> +       .reg_bits       = 5,
> +       .reg_stride     = 1,
> +       .val_bits       = 8,
> +       .reg_read       = adda_reg_read,
> +       .reg_write      = adda_reg_write,
> +       .fast_io        = true,
> +       .max_register   = 24,
> +};
> +
> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
> +
> +static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
> +                      sun8i_codec_headphone_volume_scale),
> +
> +       /* Playback Switch */
> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
> +                  1, 0),
> +
> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
> +};
> +
> +/* headphone controls */
> +static const char * const sun8i_codec_hp_src_enum_text[] = {
> +       "DAC", "Mixer",
> +};
> +
> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
> +                           SUN8I_ADDA_DAC_PA_SRC,
> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
> +                           sun8i_codec_hp_src_enum_text);
> +
> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
> +                     sun8i_codec_hp_src_enum),
> +};
> +
> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
> +};
> +
> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
> +       /* Mixers */
> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +
> +       /* Headphone output path */
> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
> +
> +       /* Headphone outputs */
> +       SND_SOC_DAPM_OUTPUT("HP"),
> +
> +};
> +
> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
> +       /* Left Mixer Routes */
> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
> +
> +       /* Right Mixer Routes */
> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
> +
> +       /* Headphone Routes */
> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
> +       { "HP", NULL, "Headphone Amp" },
> +};
> +
> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
> +       .name                   = "sun8i-codec-analog",
> +       .controls               = sun8i_analog_widgets,
> +       .num_controls           = ARRAY_SIZE(sun8i_analog_widgets),
> +       .dapm_widgets           = sun8i_codec_analog_dapm_widgets,
> +       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
> +       .dapm_routes            = sun8i_codec_analog_dapm_routes,
> +       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
> +};
> +
> +static const struct of_device_id sun8i_codec_analog_of_match[] = {
> +       { .compatible = "allwinner,sun8i-codec-analog", },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
> +
> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
> +{
> +       struct resource *res;
> +       struct regmap *regmap;
> +       void __iomem *base;
> +
> +       /* Get PRCM resources and registers */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(base)) {
> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
> +               return PTR_ERR(base);
> +       }
> +
> +       regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
> +       if (IS_ERR(regmap)) {
> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
> +               return PTR_ERR(regmap);
> +       }
> +
> +       return devm_snd_soc_register_component(&pdev->dev,
> +                                              &sun8i_codec_analog_cmpnt_drv,
> +                                              NULL, 0);
> +}
> +
> +static struct platform_driver sun8i_codec_analog_driver = {
> +       .driver = {
> +               .name = "sun8i-codec-analog",
> +               .of_match_table = sun8i_codec_analog_of_match,
> +       },
> +       .probe = sun8i_codec_analog_probe,
> +};
> +module_platform_driver(sun8i_codec_analog_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
Does the A31s have the prcm for the codec?, as I was under the
impression that it was the same as the A31 and I can't seem to find a
datasheet for that SoC. You could also add H3 and A64 here.
CK
> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec-analog");
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v26 0/7] arm64: add kdump support
From: Mark Rutland @ 2016-10-04 10:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1ae717d6-b2aa-105b-4f47-d879882ca5d3@caviumnetworks.com>

On Mon, Oct 03, 2016 at 06:11:40PM +0530, Manish Jaggi wrote:
> On 10/03/2016 04:34 PM, AKASHI Takahiro wrote:
> > On Mon, Oct 03, 2016 at 01:24:34PM +0530, Manish Jaggi wrote:
> >> Observations:
> >> 1.1. Dump capture kernel shows different memory map.
> >> ---------------------------------------------------
> >> In dump capture kernel /proc/meminfo and /proc/iomem differ
> >>
> >> root at arm64:/home/ubuntu/CODE/crash#
> >> MemTotal:       65882432 kB
> >> MemFree:        65507136 kB
> >> MemAvailable:   60373632 kB
> >> Buffers:           29248 kB
> >> Cached:            46720 kB
> >> SwapCached:            0 kB
> >> Active:            63872 kB
> >> Inactive:          19776 kB
> >> Active(anon):       8256 kB
> >> Inactive(anon):     7616 kB
> >>
> >> First kernel is booted with mem=2G crashkernel=1G command line option.
> >> While the system has 64G memory.
> >>
> >> root at arm64:/home/ubuntu/CODE/crash# cat /proc/iomem
> >> 41400000-fffeffff : System RAM
> >>   41480000-420cffff : Kernel code
> >>   42490000-4278ffff : Kernel data
> >> ffff0000-ffffffff : reserved
> >> 100000000-ffaa7ffff : System RAM
> >> ffaa80000-ffaabffff : reserved
> >> ffaac0000-fffa6ffff : System RAM
> >> fffa70000-fffacffff : reserved
> >> fffad0000-fffffffff : System RAM
> > 
> > Are you saying that "mem=..." doesn't have any effect?
> What I am saying it that If the first kernel is booted using mem= option and crashkernel= option
> the memory for second kernel has to be withing the crashkernel size.

Please don't try to use mem= to limit the kernel to a specific range of
memory. It's really only there as a tool to test handling of low-memory
situations. 

While it guarantees that at most, the amount requested will be used
(modulo a number of edge cases with reserved memory ranges), it does not
guarantee *which* memory will be used. It is *very* fragile.

Thanks,
Mark.

^ permalink raw reply


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