* [PATCH] pwm: imx: Port "pwm: imx: support output polarity inversion" to Linux v4.7
From: Lukasz Majewski @ 2016-09-30 6:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160911110112.564df4ab@jawa>
Dear all,
> Dear Lothar, Stefan,
>
> > This patch ports "pwm: imx: support output polarity inversion" patch
> > set written by Lothar Wassmann (v6 from 10.2014).
> >
>
> I've read the e-mail from Stefan regarding missing support for pwm-imx
> polarity inversion feature.
>
> I also would like to see it in ML. Hence, my patch. Lothar, please
> feel free to squash it to your patches when you (I hope :-) ) will
> prepare v7 of this feature.
>
> I hope that this would help.
Was there any decision about those patches?
Would they be included to main line anytime soon?
Best regards,
?ukasz Majewski
>
> Best regards,
> ?ukasz Majewski
>
> > It is used to control backlight of panels via inverted PWM signal.
> >
> > The "inversion" of PWM output is not an issue at such devices, since
> > separate GPIO pin is responsible for enabling and disabling the
> > panel's backlight.
> >
> > This patch should be put on top of:
> >
> > https://patchwork.kernel.org/patch/5065841/
> > https://patchwork.kernel.org/patch/5065821/
> > https://patchwork.kernel.org/patch/5065811/
> >
> >
> > Signed-off-by: Lukasz Majewski <l.majewski@majess.pl>
> > ---
> > drivers/pwm/pwm-imx.c | 20 ++++++++++++++------
> > 1 file changed, 14 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
> > index 471a99e..c37d223 100644
> > --- a/drivers/pwm/pwm-imx.c
> > +++ b/drivers/pwm/pwm-imx.c
> > @@ -181,7 +181,7 @@ static int imx_pwm_config_v2(struct pwm_chip
> > *chip, if (enable)
> > cr |= MX3_PWMCR_EN;
> >
> > - if (pwm->polarity == PWM_POLARITY_INVERSED)
> > + if (pwm->args.polarity == PWM_POLARITY_INVERSED)
> > cr |= MX3_PWMCR_POUTC;
> >
> > writel(cr, imx->mmio_base + MX3_PWMCR);
> > @@ -201,11 +201,6 @@ static void imx_pwm_set_enable_v2(struct
> > pwm_chip *chip, bool enable) else
> > val &= ~MX3_PWMCR_EN;
> >
> > - if (chip->pwms[0].polarity == PWM_POLARITY_INVERSED)
> > - val |= MX3_PWMCR_POUTC;
> > - else
> > - val &= ~MX3_PWMCR_POUTC;
> > -
> > writel(val, imx->mmio_base + MX3_PWMCR);
> > }
> >
> > @@ -253,6 +248,19 @@ static int imx_pwm_set_polarity(struct pwm_chip
> > *chip, struct pwm_device *pwm, enum pwm_polarity polarity)
> > {
> > struct imx_chip *imx = to_imx_chip(chip);
> > + u32 val;
> > +
> > + if (polarity == pwm->args.polarity)
> > + return 0;
> > +
> > + val = readl(imx->mmio_base + MX3_PWMCR);
> > +
> > + if (polarity == PWM_POLARITY_INVERSED)
> > + val |= MX3_PWMCR_POUTC;
> > + else
> > + val &= ~MX3_PWMCR_POUTC;
> > +
> > + writel(val, imx->mmio_base + MX3_PWMCR);
> >
> > dev_dbg(imx->chip.dev, "%s: polarity set to %s\n",
> > __func__, polarity == PWM_POLARITY_INVERSED ? "inverted" :
> > "normal");
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160930/22860f65/attachment.sig>
^ permalink raw reply
* [PATCH] drm/mediatek: stop using drm_vblank_count() as the hw frame counter
From: YT Shen @ 2016-09-30 6:45 UTC (permalink / raw)
To: linux-arm-kernel
using drm_vblank_no_hw_counter() to eliminate kernel warning.
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index eebb7d8..e286193 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -239,7 +239,7 @@ static struct drm_driver mtk_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC,
- .get_vblank_counter = drm_vblank_count,
+ .get_vblank_counter = drm_vblank_no_hw_counter,
.enable_vblank = mtk_drm_crtc_enable_vblank,
.disable_vblank = mtk_drm_crtc_disable_vblank,
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] mmc: sdhci-of-arasan: mark sdhci_arasan_reset() static
From: Sören Brinkmann @ 2016-09-30 6:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475199459-4775-2-git-send-email-baoyou.xie@linaro.org>
On Fri, 2016-09-30 at 09:37:39 +0800, Baoyou Xie wrote:
> We get 1 warning when building kernel with W=1:
> drivers/mmc/host/sdhci-of-arasan.c:253:6: warning: no previous prototype for 'sdhci_arasan_reset' [-Wmissing-prototypes]
>
> In fact, this function is only used in the file in which it is
> declared and don't need a declaration, but can be made static.
> So this patch marks it 'static'.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
There is already a patch for this:
https://patchwork.kernel.org/patch/9349805/
S?ren
^ permalink raw reply
* ARM juno R2 board USB Issue (EHCI probe failed)
From: Sajjan, Vikas C @ 2016-09-30 4:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <37a463cb-86d5-e0d7-7e8f-50cec3d65c95@arm.com>
Hi Sudeep,
-----Original Message-----
From: Sudeep Holla [mailto:sudeep.holla at arm.com]
Sent: Tuesday, September 27, 2016 2:38 PM
To: Sajjan, Vikas C <vikas.cha.sajjan@hpe.com>; Vikas Sajjan <sajjan.linux@gmail.com>; linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-acpi at vger.kernel.org
Cc: Sudeep Holla <sudeep.holla@arm.com>; mark.rutland at arm.com; lorenzo.pieralisi at arm.com
Subject: Re: ARM juno R2 board USB Issue (EHCI probe failed)
On 27/09/16 09:55, Sajjan, Vikas C wrote:
> Hi Sudeep,
>
> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: Tuesday, September 27, 2016 2:21 PM
> To: Vikas Sajjan <sajjan.linux@gmail.com>; linux-usb at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-acpi at vger.kernel.org
> Cc: Sudeep Holla <sudeep.holla@arm.com>; mark.rutland at arm.com;
> lorenzo.pieralisi at arm.com; Sajjan, Vikas C <vikas.cha.sajjan@hpe.com>
> Subject: Re: ARM juno R2 board USB Issue (EHCI probe failed)
>
> Hi Vikas,
>
> On 27/09/16 09:14, Vikas Sajjan wrote:
>> Adding USB mailing list.
>>
>>
>> On Tue, Sep 27, 2016 at 12:33 PM, Sajjan, Vikas C
>> <vikas.cha.sajjan@hpe.com> wrote:
>>> Hi All,
>>>
>>> I working on ARM juno R2 board, with latest kernel 4.8.rc7 and I get
>>> below USB EHCI probe error while booting with acpi=force.
>>>
>
> Are you using the latest UEFI EDK2 ?
> No, I am still using the UEFI binary which came as part of the Juno board.
>
>
>>> [ 1.223662] VFIO - User Level meta-driver version: 0.3
>>> [ 1.229335] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
>>> [ 1.235882] ehci-pci: EHCI PCI platform driver
>>> [ 1.240359] ehci-platform: EHCI generic platform driver
>>> [ 1.245619] ehci-platform ARMH0D20:00: Error: DMA mask configuration failed
>>> [ 1.272491] ehci-platform: probe of ARMH0D20:00 failed with error -5
>>> [ 1.278876] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
>>> [ 1.285071] ohci-pci: OHCI PCI platform driver
>>> [ 1.289548] ohci-platform: OHCI generic platform driver
>>> [ 1.294884] usbcore: registered new interface driver usb-storage
>>> [ 1.301231] mousedev: PS/2 mouse device common for all mice
>>> [ 1.307197] rtc-efi rtc-efi: rtc core: registered rtc-efi as rtc0
>>>
>>> But this error goes off, if I don't force ACPI booting, i.e., if I
>>> remove acpi=force from kernel command line , USB is detected and my
>>> RFS which is in the usb drive, gets mounted successfully.
>>>
>
> As I mentioned in private, I do get the same error if I drop _CCA in
> USB object of ACPI DSDT. Can you give it a spin with latest UEFI ?
>
> Sure, will try with latest UEFI.
>
I bet that's 8-12 months old. It puts the banner during boot with the build date. You can try to follow [1] or access it from [2]
I was able boot the kernel without any EHCI failure and could get to the shell prompt using the EDK2 in [2].
Thanks for help.
Thanks and Regards
Vikas Sajjan
--
Regards,
Sudeep
[1] https://community.arm.com/docs/DOC-11395
[2]
http://snapshots.linaro.org/member-builds/armlt-platforms-release/32/juno-uefi.zip
^ permalink raw reply
* [PATCH 0/4] Add DMA support for ti_am335x_adc driver
From: John Syne @ 2016-09-30 3:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ff19f584-e4e5-61ff-046d-68ec37ab51c2@ti.com>
I applied your patches to the following kernel:
github.com/RobertCNelson/bb-kernel.git
branch am33x-v4.8
Changing
#define REG_DMAENABLE_CLEAR 0x038
to
#define REG_DMAENABLE_CLEAR 0x03C
Also applying the following DTS changes:
target = <&tscadc>;
__overlay__ {
status = "okay";
adc {
ti,adc-channels = <0 1 2 3 4 5 6>;
ti,chan-step-avg = <0x1 0x1 0x1 0x1 0x1 0x1 0x1>;
ti,chan-step-opendelay = <0x0 0x0 0x0 0x0 0x0 0x0 0x0>;
ti,chan-step-sampledelay = <0x0 0x0 0x0 0x0 0x0 0x0 0x0>;
};
};
Running on a BeagleBoneBlack, I was able to stream samples at 200ksps continuously and it looked stable.
htop showed CPU utilization between 5% and 7%
Thank you for getting this to work.
Regards,
John
> On Sep 29, 2016, at 6:01 AM, Mugunthan V N <mugunthanvnm@ti.com> wrote:
>
> On Sunday 25 September 2016 03:11 PM, Jonathan Cameron wrote:
>> On 21/09/16 17:11, Mugunthan V N wrote:
>>>> The ADC has a 64 work depth fifo length which holds the ADC data
>>>> till the CPU reads. So when a user program needs a large ADC data
>>>> to operate on, then it has to do multiple reads to get its
>>>> buffer. Currently if the application asks for 4 samples per
>>>> channel with all 8 channels are enabled, kernel can provide only
>>>> 3 samples per channel when all 8 channels are enabled (logs at
>>>> [1]). So with DMA support user can request for large number of
>>>> samples at a time (logs at [2]).
>>>>
>>>> Tested the patch on AM437x-gp-evm and AM335x Boneblack with the
>>>> patch [3] to enable ADC and pushed a branch for testing [4]
>>>>
>>>> [1] - http://pastebin.ubuntu.com/23211490/
>>>> [2] - http://pastebin.ubuntu.com/23211492/
>>>> [3] - http://pastebin.ubuntu.com/23211494/
>>>> [4] - git://git.ti.com/~mugunthanvnm/ti-linux-kernel/linux.git iio-dma
>> Just curious. How fast is the ADC sampling at in these? Never that
>> obvious for this driver!
>>
>> I'm also curious as to whether you started to hit the limits of the
>> kfifo based interface. Might be worth considering adding alternative
>> support for the dma buffers interface which is obviously much lower
>> overhead.
>>
>> Good to have this work prior to that as the kfifo stuff is somewhat
>> easier to use.
>
> Currently ADC clock is 3MHz, which can produce a data rate of 225KBps
> per channel with no open delay and no averaging of samples. So when all
> 8 Channels are enables the data rate will be 1.75MBps
>
> ADC can be operated at 24MHz, which can generate a data rate of 28MBps
> with all 8 channels enabled and no open delay and averaging, but our
> target is to get 800K samples per second per channel which has a data
> rate of 12.5MBps
>
> I think with this data rate, DMA will be the best option to implement
> without any data loss and less cpu overload to read the ADC samples.
>
> Regards
> Mugunthan V N
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] drm/mediatek: fix a typo
From: Bibby Hsieh @ 2016-09-30 3:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1f324471-bebb-c8bf-75c1-391355c50a99@gmail.com>
On Thu, 2016-09-29 at 10:46 +0200, Matthias Brugger wrote:
>
> On 29/09/16 06:01, CK Hu wrote:
> > Acked-by: CK Hu <ck.hu@mediatek.com>
> >
> > On Thu, 2016-09-29 at 11:22 +0800, Bibby Hsieh wrote:
> >> Fix the typo: OD_RELAYMODE->OD_CFG
> >>
>
Hi, Matthias
Thanks for your reply.
> Although it is quite clear what the patch does, could you write one
> sentence to explain what it does. Maybe explain even which effect it
> has, which error get fixed etc.
Ok, I will do that.
> As we are getting public available boards now, we should take more care
> about fixes. If you have a fix for a commit introduced in an earlier
> version of linux and it should be fixed for this version as well (e.g.
> v4.6 does have the feature but it does not work correctly) then please
> add these two lines before your Signed-off-by:
> Fixes: <commit-hash> ("<commit subject line>")
> Cc: stable at vger.kernel.org # v4.6+
>
> Where v4.6+ stands for the oldest version where this should get fixed.
>
Ok, but the patch hasn't been merged into v4.8 (just in drm-next [1] and
linux-next [2]), how can I mark that?
[1]
https://cgit.freedesktop.org/~airlied/linux/commit/?h=drm-next&id=7216436420414144646f5d8343d061355fd23483
[2]
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/?id=7216436420414144646f5d8343d061355fd23483
> Thanks a lot,
> Matthias
>
> >> Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
> >> ---
> >> drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 +-
> >> 1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> >> index df33b3c..aa5f20f 100644
> >> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> >> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> >> @@ -123,7 +123,7 @@ static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
> >> unsigned int bpc)
> >> {
> >> writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
> >> - writel(OD_RELAYMODE, comp->regs + OD_RELAYMODE);
> >> + writel(OD_RELAYMODE, comp->regs + OD_CFG);
> >> mtk_dither_set(comp, bpc, DISP_OD_CFG);
> >> }
> >>
> >
> >
--
Bibby
^ permalink raw reply
* [PATCH v14 2/4] CMDQ: Mediatek CMDQ driver
From: CK Hu @ 2016-09-30 3:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473039885-24009-3-git-send-email-hs.liao@mediatek.com>
Hi, HS:
On Mon, 2016-09-05 at 09:44 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
>
> Signed-off-by: HS Liao <hs.liao@mediatek.com>
> Signed-off-by: CK Hu <ck.hu@mediatek.com>
> ---
[snip...]
> +
> +struct cmdq_task {
> + struct cmdq *cmdq;
> + struct list_head list_entry;
> + void *va_base;
> + dma_addr_t pa_base;
> + size_t cmd_buf_size; /* command occupied size */
> + size_t buf_size; /* real buffer size */
> + bool finalized;
> + struct cmdq_thread *thread;
I think thread info could be removed from cmdq_task. Only
cmdq_task_handle_error() and cmdq_task_insert_into_thread() use
task->thread and caller of both function has the thread info. So you
could just pass thread info into these two function and remove thread
info in cmdq_task.
> + struct cmdq_task_cb cb;
I think this callback function is equal to mailbox client tx_done
callback. It's better to use already-defined interface rather than
creating your own.
> +};
> +
[snip...]
> +
> +static int cmdq_suspend(struct device *dev)
> +{
> + struct cmdq *cmdq = dev_get_drvdata(dev);
> + struct cmdq_thread *thread;
> + int i;
> + bool task_running = false;
> +
> + mutex_lock(&cmdq->task_mutex);
> + cmdq->suspended = true;
> + mutex_unlock(&cmdq->task_mutex);
> +
> + for (i = 0; i < ARRAY_SIZE(cmdq->thread); i++) {
> + thread = &cmdq->thread[i];
> + if (!list_empty(&thread->task_busy_list)) {
> + mod_timer(&thread->timeout, jiffies + 1);
> + task_running = true;
> + }
> + }
> +
> + if (task_running) {
> + dev_warn(dev, "exist running task(s) in suspend\n");
> + msleep(20);
Why sleep here? It looks like a recovery but could 20ms recovery
something? I think warning message is enough because you see the warning
message, and you fix the bug, so no need to recovery anything.
> + }
> +
> + clk_unprepare(cmdq->clock);
> + return 0;
> +}
> +
Regards,
CK
^ permalink raw reply
* [PATCH 3/3] arm64: dump: Add checking for writable and exectuable pages
From: Mark Rutland @ 2016-09-30 2:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160929213257.30505-4-labbott@redhat.com>
Hi,
On Thu, Sep 29, 2016 at 02:32:57PM -0700, Laura Abbott wrote:
> Page mappings with full RWX permissions are a security risk. x86
> has an option to walk the page tables and dump any bad pages.
> (See e1a58320a38d ("x86/mm: Warn on W^X mappings")). Add a similar
> implementation for arm64.
>
> Signed-off-by: Laura Abbott <labbott@redhat.com>
> @@ -31,6 +32,8 @@ struct ptdump_info {
> const struct addr_marker *markers;
> unsigned long base_addr;
> unsigned long max_addr;
(unrelated aside: it looks like max_addr is never used or even assigned to;
care to delete it in a prep patch?)
> + /* Internal, do not touch */
> + struct list_head node;
> };
> +static LIST_HEAD(dump_info);
With the EFI runtime map tables it's unfortunately valid (and very likely with
64K pages) that there will be RWX mappings, at least with contemporary versions
of the UEFI spec. Luckily, those are only installed rarely and transiently.
Given that (and other potential ptdump users), I don't think we should have a
dynamic list of ptdump_infos for W^X checks, and should instead have
ptdump_check_wx() explicitly check the tables we care about. More comments
below on that.
I think we only care about the swapper and hyp tables, as nothing else is
permanent. Does that sound sane?
> struct prot_bits {
> @@ -219,6 +223,15 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
> unsigned long delta;
>
> if (st->current_prot) {
> + if (st->check_wx &&
> + ((st->current_prot & PTE_RDONLY) != PTE_RDONLY) &&
> + ((st->current_prot & PTE_PXN) != PTE_PXN)) {
> + WARN_ONCE(1, "arm64/mm: Found insecure W+X mapping at address %p/%pS\n",
> + (void *)st->start_address,
> + (void *)st->start_address);
> + st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
> + }
> +
Currently note_page() is painful to read due to the indentation and logic.
Rather than adding to that, could we factor this into a helper? e.g.
note_prot_wx(struct pg_state *st, unsigned long addr)
{
if (!st->check_wx)
return;
if ((st->current_prot & PTE_RDONLY) == PTE_RDONLY)
return;
if ((st->current_prot & PTE_PXN) == PTE_PXN)
return;
WARN_ONCE(1, "arm64/mm: Found insecure W+X mapping at address %p/%pS\n",
(void *)st->start_address, (void *)st->start_address);
st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
}
> +void ptdump_check_wx(void)
> +{
> + struct ptdump_info *info;
> +
> + list_for_each_entry(info, &dump_info, node) {
> + struct pg_state st = {
> + .seq = NULL,
> + .marker = info->markers,
> + .check_wx = true,
> + };
> +
> + __walk_pgd(&st, info->mm, info->base_addr);
> + note_page(&st, 0, 0, 0);
> + if (st.wx_pages)
> + pr_info("Checked W+X mappings (%p): FAILED, %lu W+X pages found\n",
> + info->mm,
> + st.wx_pages);
> + else
> + pr_info("Checked W+X mappings (%p): passed, no W+X pages found\n", info->mm);
> + }
> +}
As above, I don't think we should use a list of arbitrary ptdump_infos.
Given we won't log addresses in the walking code, I think that we can make up a
trivial marker array, and then just use init_mm direct, e.g. (never even
compile-tested):
void ptdump_check_wx(void)
{
struct pg_state st = {
.seq = NULL,
.marker = (struct addr_markers[]) {
{ -1, NULL},
},
.check_wx = true,
};
__walk_pgd(&st, init_mm, 0);
note_page(&st, 0, 0, 0);
if (st.wx_pages)
pr_info("Checked W+X mappings (%p): FAILED, %lu W+X pages found\n",
info->mm,
st.wx_pages);
else
pr_info("Checked W+X mappings (%p): passed, no W+X pages found\n", info->mm);
}
Otherwise, this looks good to me. Thanks for putting this together!
Mark.
^ permalink raw reply
* [PATCH v2 2/2] drm: zte: add initial vou drm driver
From: Shawn Guo @ 2016-09-30 1:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOw6vbKh9x5hxWLO2JswYH8Qw1xdB1Xc5c9nVDZ0WxsQRxhX0Q@mail.gmail.com>
Hi Sean,
On Tue, Sep 27, 2016 at 11:48:37AM -0400, Sean Paul wrote:
> On Sat, Sep 24, 2016 at 10:26 AM, Shawn Guo <shawn.guo@linaro.org> wrote:
> > It adds the initial ZTE VOU display controller DRM driver. There are
> > still some features to be added, like overlay plane, scaling, and more
> > output devices support. But it's already useful with dual CRTCs and
> > HDMI monitor working.
> >
> > It's been tested on Debian Jessie LXDE desktop with modesetting driver.
> >
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
>
> Hi Shawn,
> I think overall this is very well done! A couple of things stuck out
> to me, I've pointed them out below, hopefully you can use some of
> them.
Thanks for reviewing the patch. The comments are helpful, and I will
try to address them immediately once I get back from the business
travel.
> > diff --git a/drivers/gpu/drm/zte/Makefile b/drivers/gpu/drm/zte/Makefile
> > new file mode 100644
> > index 000000000000..b40968dc749f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/zte/Makefile
> > @@ -0,0 +1,8 @@
> > +zxdrm-y := \
> > + zx_drm_drv.o \
> > + zx_crtc.o \
> > + zx_plane.o \
> > + zx_hdmi.o
> > +
> > +obj-$(CONFIG_DRM_ZTE) += zxdrm.o
> > +
> > diff --git a/drivers/gpu/drm/zte/zx_crtc.c b/drivers/gpu/drm/zte/zx_crtc.c
>
> I was a little tripped up when I first read this file since I assumed
> there was one instance of this driver per-crtc. However, there's
> really N crtcs per driver. Might it be less confusing to call it
> zx_vou.c instead?
Okay, will rename it.
> > +static void zx_crtc_enable(struct drm_crtc *crtc)
> > +{
> > + struct drm_display_mode *mode = &crtc->state->adjusted_mode;
> > + struct zx_crtc *zcrtc = to_zx_crtc(crtc);
> > + struct zx_vou_hw *vou = dev_get_drvdata(zcrtc->dev);
>
> IMO, it would be better to store a pointer to vou in each zx_crtc
> rather than reaching into drvdata.
Yeah, agree on that.
> > + bool is_main = is_main_crtc(crtc);
> > + struct videomode vm;
> > + u32 pol = 0;
> > + u32 val;
> > +
> > + drm_display_mode_to_videomode(mode, &vm);
>
> Why do this conversion? You should be able to get everything you need
> from drm_display_mode
It's a helper function, and the calculation of front_porch, back_porch
and sync_len helps me.
> > +
> > + /* Set up timing parameters */
> > + val = (vm.vactive - 1) << 16;
> > + val |= (vm.hactive - 1) & 0xffff;
> > + writel(val, vou->timing + (is_main ? FIR_MAIN_ACTIVE : FIR_AUX_ACTIVE));
> > +
> > + val = ((vm.hsync_len - 1) << SYNC_WIDE_SHIFT) & SYNC_WIDE_MASK;
> > + val |= ((vm.hback_porch - 1) << BACK_PORCH_SHIFT) & BACK_PORCH_MASK;
> > + val |= ((vm.hfront_porch - 1) << FRONT_PORCH_SHIFT) & FRONT_PORCH_MASK;
> > + writel(val, vou->timing + (is_main ? FIR_MAIN_H_TIMING :
> > + FIR_AUX_H_TIMING));
> > +
> > + val = ((vm.vsync_len - 1) << SYNC_WIDE_SHIFT) & SYNC_WIDE_MASK;
> > + val |= ((vm.vback_porch - 1) << BACK_PORCH_SHIFT) & BACK_PORCH_MASK;
> > + val |= ((vm.vfront_porch - 1) << FRONT_PORCH_SHIFT) & FRONT_PORCH_MASK;
> > + writel(val, vou->timing + (is_main ? FIR_MAIN_V_TIMING :
> > + FIR_AUX_V_TIMING));
>
> It would be nice to figure out a better way of handing the main/aux
> switch as opposed to sprinkling all of these inline conditionals
> around. Perhaps you could introduce a struct which stores the
> addresses per-crtc and then reference the struct in the driver as
> opposed to the #defines.
>
> ie:
>
> writel(val, vou->timing + zcrtc->regs->v_timing);
Yeah, good suggestion.
> > +static void zx_crtc_atomic_begin(struct drm_crtc *crtc,
> > + struct drm_crtc_state *state)
> > +{
> > + struct drm_pending_vblank_event *event = crtc->state->event;
> > +
> > + if (event) {
>
> nit: you can save yourself a level of indentation by exiting early on
> !event instead of scoping the entire function on event.
Aha, right!
>
> > + crtc->state->event = NULL;
> > +
> > + spin_lock_irq(&crtc->dev->event_lock);
> > + if (drm_crtc_vblank_get(crtc) == 0)
> > + drm_crtc_arm_vblank_event(crtc, event);
> > + else
> > + drm_crtc_send_vblank_event(crtc, event);
> > + spin_unlock_irq(&crtc->dev->event_lock);
> > + }
> > +}
<snip>
> > +static struct zx_crtc *zx_crtc_init(struct drm_device *drm,
> > + enum vou_chn_type chn_type)
> > +{
> > + struct zx_drm_private *priv = drm->dev_private;
> > + struct zx_vou_hw *vou = priv->vou;
> > + struct device *dev = vou->dev;
> > + struct zx_layer_data data;
> > + struct zx_crtc *zcrtc;
> > + int ret;
> > +
> > + zcrtc = devm_kzalloc(dev, sizeof(*zcrtc), GFP_KERNEL);
> > + if (!zcrtc)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + zcrtc->dev = dev;
> > + zcrtc->chn_type = chn_type;
> > +
> > + if (chn_type == VOU_CHN_MAIN) {
> > + data.layer = vou->osd + 0x130;
> > + data.csc = vou->osd + 0x580;
> > + data.hbsc = vou->osd + 0x820;
> > + data.rsz = vou->otfppu + 0x600;
> > + zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
> > + } else {
> > + data.layer = vou->osd + 0x200;
> > + data.csc = vou->osd + 0x5d0;
> > + data.hbsc = vou->osd + 0x860;
> > + data.rsz = vou->otfppu + 0x800;
> > + zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
> > + }
>
> These magic values should find their way into #defines
Yeah, will do.
> > +static void vou_dtrc_init(struct zx_vou_hw *vou)
> > +{
> > + u32 val;
> > +
> > + val = readl(vou->dtrc + DTRC_DETILE_CTRL);
> > + /* Clear bit for bypass by ID */
> > + val &= ~TILE2RASTESCAN_BYPASS_MODE;
> > + /* Select ARIDR mode */
> > + val &= ~DETILE_ARIDR_MODE_MASK;
> > + val |= DETILE_ARID_IN_ARIDR;
> > + writel(val, vou->dtrc + DTRC_DETILE_CTRL);
> > +
> > + /* Bypass decompression for both frames */
> > + val = readl(vou->dtrc + DTRC_F0_CTRL);
> > + val |= DTRC_DECOMPRESS_BYPASS;
> > + writel(val, vou->dtrc + DTRC_F0_CTRL);
> > +
> > + val = readl(vou->dtrc + DTRC_F1_CTRL);
> > + val |= DTRC_DECOMPRESS_BYPASS;
> > + writel(val, vou->dtrc + DTRC_F1_CTRL);
> > +
> > + /* Set up ARID register */
> > + val = 0x0e;
> > + val |= 0x0f << 8;
> > + val |= 0x0e << 16;
> > + val |= 0x0f << 24;
>
> #define
Okay.
> > +static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
> > +{
> > + struct platform_device *pdev = to_platform_device(dev);
> > + struct drm_device *drm = data;
> > + struct zx_drm_private *priv = drm->dev_private;
> > + struct resource *res;
> > + struct zx_vou_hw *vou;
> > + int irq;
> > + int ret;
> > +
> > + vou = devm_kzalloc(dev, sizeof(*vou), GFP_KERNEL);
> > + if (!vou)
> > + return -ENOMEM;
> > +
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osd");
> > + vou->osd = devm_ioremap_resource(dev, res);
> > + if (IS_ERR(vou->osd))
> > + return PTR_ERR(vou->osd);
> > +
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "timing_ctrl");
> > + vou->timing = devm_ioremap_resource(dev, res);
> > + if (IS_ERR(vou->timing))
> > + return PTR_ERR(vou->timing);
> > +
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dtrc");
> > + vou->dtrc = devm_ioremap_resource(dev, res);
> > + if (IS_ERR(vou->dtrc))
> > + return PTR_ERR(vou->dtrc);
> > +
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vou_ctrl");
> > + vou->vouctl = devm_ioremap_resource(dev, res);
> > + if (IS_ERR(vou->vouctl))
> > + return PTR_ERR(vou->vouctl);
> > +
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otfppu");
> > + vou->otfppu = devm_ioremap_resource(dev, res);
> > + if (IS_ERR(vou->otfppu))
> > + return PTR_ERR(vou->otfppu);
> > +
> > + irq = platform_get_irq(pdev, 0);
> > + if (irq < 0)
> > + return irq;
> > +
> > + vou->axi_clk = devm_clk_get(dev, "aclk");
> > + if (IS_ERR(vou->axi_clk))
> > + return PTR_ERR(vou->axi_clk);
> > +
> > + vou->ppu_clk = devm_clk_get(dev, "ppu_wclk");
> > + if (IS_ERR(vou->ppu_clk))
> > + return PTR_ERR(vou->ppu_clk);
> > +
> > + clk_prepare_enable(vou->axi_clk);
> > + clk_prepare_enable(vou->ppu_clk);
> > +
> > + vou->dev = dev;
> > + priv->vou = vou;
> > + dev_set_drvdata(dev, vou);
>
> I think you should be able to avoid storing vou in priv and drvdata.
I see I can do something by avoid storing vou in priv, but not sure how
to access vou in unbind function without storing it in drvdata. Any
suggestion?
> > +
> > + vou_hw_init(vou);
> > +
> > + ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou);
> > + if (ret < 0)
> > + return ret;
> > +
> > + vou->main_crtc = zx_crtc_init(drm, VOU_CHN_MAIN);
> > + if (IS_ERR(vou->main_crtc))
> > + return PTR_ERR(vou->main_crtc);
> > +
> > + vou->aux_crtc = zx_crtc_init(drm, VOU_CHN_AUX);
> > + if (IS_ERR(vou->aux_crtc))
> > + return PTR_ERR(vou->aux_crtc);
> > +
> > + return 0;
> > +}
<snip>
> > diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
> > new file mode 100644
> > index 000000000000..51fafb8e5f43
> > --- /dev/null
> > +++ b/drivers/gpu/drm/zte/zx_drm_drv.c
> > @@ -0,0 +1,258 @@
> > +/*
> > + * Copyright 2016 Linaro Ltd.
> > + * Copyright 2016 ZTE Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/clk.h>
> > +#include <linux/component.h>
> > +#include <linux/list.h>
> > +#include <linux/of_graph.h>
> > +#include <linux/of_platform.h>
>
> nit: Alphabetical?
Okay, will do.
> > +static struct vou_inf vou_inf_hdmi = {
> > + .id = VOU_HDMI,
> > + .data_sel = VOU_YUV444,
> > + .clocks_en_bits = BIT(24) | BIT(18) | BIT(6),
> > + .clocks_sel_bits = BIT(13) | BIT(2),
> > +};
>
> This should be static const, but I suppose you can't b/c you're
> storing a pointer to encoder in vou_inf. This type of information
> lends itself well to being defined and mapped as of_device_id.data,
> you'll need to pass the encoder around in a different manner.
Okay, I will find some way to remove the encoder pointer out of the
structure.
> > +static int zx_hdmi_config_video_vsi(struct zx_hdmi *hdmi,
> > + struct drm_display_mode *mode)
> > +{
> > + union hdmi_infoframe frame;
> > + int ret;
> > +
> > + ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
> > + mode);
> > + if (ret)
>
> Should you log in cases of failure (here and elsewhere)?
Okay, will do.
> > + return ret;
> > +
> > + return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_VSIF);
> > +}
<snip>
> > +static void zx_hdmi_encoder_enable(struct drm_encoder *encoder)
> > +{
> > + struct zx_hdmi *hdmi = to_zx_hdmi(encoder);
> > +
> > + vou_inf_enable(hdmi->inf);
>
> I think you can remove the encoder from inf by passing encoder->crtc
> here as well. That will tell vou which encoder/crtc pair to enable
> without having that pesky static global floating around.
Yes.
> > +}
> > +
> > +static void zx_hdmi_encoder_disable(struct drm_encoder *encoder)
> > +{
> > + struct zx_hdmi *hdmi = to_zx_hdmi(encoder);
> > +
> > + vou_inf_disable(hdmi->inf);
>
> Same here
Yes.
> > +}
> > +
> > +static const struct drm_encoder_helper_funcs zx_hdmi_encoder_helper_funcs = {
> > + .enable = zx_hdmi_encoder_enable,
> > + .disable = zx_hdmi_encoder_disable,
> > + .mode_set = zx_hdmi_encoder_mode_set,
> > +};
> > +
> > +static const struct drm_encoder_funcs zx_hdmi_encoder_funcs = {
> > + .destroy = drm_encoder_cleanup,
> > +};
> > +
> > +static int zx_hdmi_get_edid_block(void *data, u8 *buf, unsigned int block,
> > + size_t len)
>
> Instead of open-coding this, consider implementing an i2c adapter for
> the DDC bus and use drm_get_edid below.
Okay. I got the same suggestion from Daniel, so it must be something
good :)
Shawn
^ permalink raw reply
* [PATCH 2/2] mmc: sdhci-of-arasan: mark sdhci_arasan_reset() static
From: Baoyou Xie @ 2016-09-30 1:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475199459-4775-1-git-send-email-baoyou.xie@linaro.org>
We get 1 warning when building kernel with W=1:
drivers/mmc/host/sdhci-of-arasan.c:253:6: warning: no previous prototype for 'sdhci_arasan_reset' [-Wmissing-prototypes]
In fact, this function is only used in the file in which it is
declared and don't need a declaration, but can be made static.
So this patch marks it 'static'.
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
drivers/mmc/host/sdhci-of-arasan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index da8e40a..e263671 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -250,7 +250,7 @@ static void sdhci_arasan_hs400_enhanced_strobe(struct mmc_host *mmc,
writel(vendor, host->ioaddr + SDHCI_ARASAN_VENDOR_REGISTER);
}
-void sdhci_arasan_reset(struct sdhci_host *host, u8 mask)
+static void sdhci_arasan_reset(struct sdhci_host *host, u8 mask)
{
u8 ctrl;
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] mmc: block: add missing header dependencies
From: Baoyou Xie @ 2016-09-30 1:37 UTC (permalink / raw)
To: linux-arm-kernel
We get 1 warning when building kernel with W=1:
drivers/mmc/card/block.c:2147:5: warning: no previous prototype for 'mmc_blk_issue_rq' [-Wmissing-prototypes]
In fact, this function is declared in drivers/mmc/card/block.h,
so this patch adds missing header dependencies.
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
drivers/mmc/card/block.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c333511..0f2cc9f2 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -46,6 +46,7 @@
#include <asm/uaccess.h>
#include "queue.h"
+#include "block.h"
MODULE_ALIAS("mmc:block");
#ifdef MODULE_PARAM_PREFIX
--
2.7.4
^ permalink raw reply related
* [kernel-hardening] [PATCH 0/3] WX Checking for arm64
From: Kees Cook @ 2016-09-30 1:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160929213257.30505-1-labbott@redhat.com>
On Thu, Sep 29, 2016 at 2:32 PM, Laura Abbott <labbott@redhat.com> wrote:
>
> Hi,
>
> This is an implementation to check for writable and executable pages on arm64.
> This is heavily based on the x86 version which uses the existing page table
> dumping code to do the checking. Some notes:
>
> - The W^X checking is important so this option should become defaut eventually.
> To make this feasible, the debugfs functionality has been split out as a
> separate option. I didn't see a good way to make it modular like x86 but
> an option should be good enough.
> - This checks all page tables registered with ptdump_register. I don't see this
> being called elsewhere right now though.
> - Once this is merged, I'd like to see about moving DEBUG_WX to the top level
> instead of having each arch call it in mark_rodata.
Awesome!
Yeah, I think we should take a look at refactoring x86, arm, and arm64
to use a common infrastructure with callbacks. That way other
architectures can gain all these features with just a few callbacks
implemented.
-Kees
>
> Laura Abbott (3):
> arm64: dump: Make ptdump debugfs a separate option
> arm64: dump: Make the page table dumping seq_file optional
> arm64: dump: Add checking for writable and exectuable pages
>
> arch/arm64/Kconfig.debug | 34 ++++++++++++++-
> arch/arm64/include/asm/ptdump.h | 25 ++++++++++-
> arch/arm64/mm/Makefile | 3 +-
> arch/arm64/mm/dump.c | 92 ++++++++++++++++++++++++++++-------------
> arch/arm64/mm/mmu.c | 2 +
> arch/arm64/mm/ptdump_debugfs.c | 33 +++++++++++++++
> 6 files changed, 157 insertions(+), 32 deletions(-)
> create mode 100644 arch/arm64/mm/ptdump_debugfs.c
>
> --
> 2.10.0
>
--
Kees Cook
Nexus Security
^ permalink raw reply
* [PATCH 1/3] arm64: dump: Make ptdump debugfs a separate option
From: Mark Rutland @ 2016-09-30 1:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cf3b51d5-f5ad-9fc3-7bea-7e7a5a9798c5@redhat.com>
On Thu, Sep 29, 2016 at 06:11:44PM -0700, Laura Abbott wrote:
> On 09/29/2016 05:48 PM, Mark Rutland wrote:
> >On Thu, Sep 29, 2016 at 05:31:09PM -0700, Laura Abbott wrote:
> >>On 09/29/2016 05:13 PM, Mark Rutland wrote:
> >>>On Thu, Sep 29, 2016 at 02:32:55PM -0700, Laura Abbott wrote:
> >>>>+int ptdump_register(struct ptdump_info *info, const char *name)
> >>>>+{
> >>>>+ ptdump_initialize(info);
> >>>>+ return ptdump_debugfs_create(info, name);
> >>>>}
> >I meant moving ptdump_register into ptdump_debugfs.c, perhaps renamed to make it
> >clear it's debugfs-specific.
> >
> >We could instead update existing users to call ptdump_debugfs_create()
> >directly, and have that call ptdump_initialize(), which could itself become a
> >staic inline in a header.
>
> Ah okay, I see what you are suggesting. ptdump_initialize should still
> happen regardless of debugfs status though so I guess ptdump_debugfs_create
> would just get turned into just ptdump_initialize
> which seems a little unclear. I'll come up with some other shed
> colors^W^Wfunction names.
Cheers!
FWIW, given ptsump_initialize() is only going to be called with the ptdump core
and debugfs code, I'm not all that concerned by what it's called. A few leading
underscores is about the only thing that comes to mind, but even as-is I think
it should be fine.
Thanks,
Mark.
^ permalink raw reply
* [PATCH 1/3] arm64: dump: Make ptdump debugfs a separate option
From: Laura Abbott @ 2016-09-30 1:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160930004852.GC4369@remoulade>
On 09/29/2016 05:48 PM, Mark Rutland wrote:
> On Thu, Sep 29, 2016 at 05:31:09PM -0700, Laura Abbott wrote:
>> On 09/29/2016 05:13 PM, Mark Rutland wrote:
>>> On Thu, Sep 29, 2016 at 02:32:55PM -0700, Laura Abbott wrote:
>>>> +int ptdump_register(struct ptdump_info *info, const char *name)
>>>> +{
>>>> + ptdump_initialize(info);
>>>> + return ptdump_debugfs_create(info, name);
>>>> }
>>>
>>> It feels like a layering violation to have the core ptdump code call the
>>> debugfs ptdump code. Is there some reason this has to live here?
>>
>> Which 'this' are you referring to here? Are you suggesting moving
>> the ptdump_register elsewhere or moving the debugfs create elsewhere?
>
> Sorry, I should have worded that better.
>
> I meant moving ptdump_register into ptdump_debugfs.c, perhaps renamed to make it
> clear it's debugfs-specific.
>
> We could instead update existing users to call ptdump_debugfs_create()
> directly, and have that call ptdump_initialize(), which could itself become a
> staic inline in a header.
Ah okay, I see what you are suggesting. ptdump_initialize should still
happen regardless of debugfs status though so I guess
ptdump_debugfs_create would just get turned into just ptdump_initialize
which seems a little unclear. I'll come up with some other shed
colors^W^Wfunction names.
Thanks,
Laura
^ permalink raw reply
* [PATCH 1/3] arm64: dump: Make ptdump debugfs a separate option
From: Mark Rutland @ 2016-09-30 0:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e17189c7-54e0-f0a1-2b16-36f486111c4c@redhat.com>
On Thu, Sep 29, 2016 at 05:31:09PM -0700, Laura Abbott wrote:
> On 09/29/2016 05:13 PM, Mark Rutland wrote:
> >On Thu, Sep 29, 2016 at 02:32:55PM -0700, Laura Abbott wrote:
> >>+int ptdump_register(struct ptdump_info *info, const char *name)
> >>+{
> >>+ ptdump_initialize(info);
> >>+ return ptdump_debugfs_create(info, name);
> >> }
> >
> >It feels like a layering violation to have the core ptdump code call the
> >debugfs ptdump code. Is there some reason this has to live here?
>
> Which 'this' are you referring to here? Are you suggesting moving
> the ptdump_register elsewhere or moving the debugfs create elsewhere?
Sorry, I should have worded that better.
I meant moving ptdump_register into ptdump_debugfs.c, perhaps renamed to make it
clear it's debugfs-specific.
We could instead update existing users to call ptdump_debugfs_create()
directly, and have that call ptdump_initialize(), which could itself become a
staic inline in a header.
Thanks,
Mark.
^ permalink raw reply
* [PATCH v14 0/9] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
From: Xiongfeng Wang @ 2016-09-30 0:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475086637-1914-1-git-send-email-fu.wei@linaro.org>
for sbsa watchdog part, Tested-by: wangxiongfeng2 at huawei.com on D05 board.
On 2016/9/29 2:17, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
>
> This patchset:
> (1)Preparation for adding GTDT support in arm_arch_timer:
> 1. Move some enums and marcos to header file;
> 2. Add a new enum for spi type;
> 3. Improve printk relevant code.
>
> (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
> Parse all kinds of timer in GTDT table of ACPI:arch timer,
> memory-mapped timer and SBSA Generic Watchdog timer.
> This driver can help to simplify all the relevant timer drivers,
> and separate all the ACPI GTDT knowledge from them.
>
> (3)Simplify ACPI code for arm_arch_timer
>
> (4)Add GTDT support for ARM memory-mapped timer, also refactor
> original memory-mapped timer dt support for reusing some common
> code.
>
> This patchset depends on the following patchset:
> [UPDATE PATCH V11 1/8] ACPI: I/O Remapping Table (IORT) initial support
> https://lkml.org/lkml/2016/9/12/949
>
> This patchset has been tested on the following platforms:
> (1)ARM Foundation v8 model
>
> Changelog:
> v14: https://lkml.org/lkml/2016/9/28/
> Separate memory-mapped timer GTDT support into two patches
> 1. Refactor the timer init code to prepare for GTDT
> 2. Add GTDT support for memory-mapped timer
>
> v13: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1231717.html
> Improve arm_arch_timer code for memory-mapped
> timer GTDT support, refactor original memory-mapped timer
> dt support for reusing some common code.
>
> v12: https://lkml.org/lkml/2016/9/13/250
> Rebase to latest Linux 4.8-rc6
> Delete the confusing "skipping" in the error message.
>
> V11: https://lkml.org/lkml/2016/9/6/354
> Rebase to latest Linux 4.8-rc5
> Delete typedef (suggested by checkpatch.pl)
>
> V10: https://lkml.org/lkml/2016/7/26/215
> Drop the "readq" patch.
> Rebase to latest Linux 4.7.
>
> V9: https://lkml.org/lkml/2016/7/25/345
> Improve pr_err message in acpi gtdt driver.
> Update Commit message for 7/9
> shorten the irq mapping function name
> Improve GTDT driver for memory-mapped timer
>
> v8: https://lkml.org/lkml/2016/7/19/660
> Improve "pr_fmt(fmt)" definition: add "ACPI" in front of "GTDT",
> and also improve printk message.
> Simplify is_timer_block and is_watchdog.
> Merge acpi_gtdt_desc_init and gtdt_arch_timer_init into acpi_gtdt_init();
> Delete __init in include/linux/acpi.h for GTDT API
> Make ARM64 select GTDT.
> Delete "#include <linux/module.h>" from acpi_gtdt.c
> Simplify GT block parse code.
>
> v7: https://lkml.org/lkml/2016/7/13/769
> Move the GTDT driver to drivers/acpi/arm64
> Add add the ARM64-specific ACPI Support maintainers in MAINTAINERS
> Merge 3 patches of GTDT parser driver.
> Fix the for_each_platform_timer bug.
>
> v6: https://lkml.org/lkml/2016/6/29/580
> split the GTDT driver to 4 parts: basic, arch_timer, memory-mapped timer,
> and SBSA Generic Watchdog timer
> Improve driver by suggestions and example code from Daniel Lezcano
>
> v5: https://lkml.org/lkml/2016/5/24/356
> Sorting out all patches, simplify the API of GTDT driver:
> GTDT driver just fills the data struct for arm_arch_timer driver.
>
> v4: https://lists.linaro.org/pipermail/linaro-acpi/2016-March/006667.html
> Delete the kvm relevant patches
> Separate two patches for sorting out the code for arm_arch_timer.
> Improve irq info export code to allow missing irq info in GTDT table.
>
> v3: https://lkml.org/lkml/2016/2/1/658
> Improve GTDT driver code:
> (1)improve pr_* by defining pr_fmt(fmt)
> (2)simplify gtdt_sbsa_gwdt_init
> (3)improve gtdt_arch_timer_data_init, if table is NULL, it will try
> to get GTDT table.
> Move enum ppi_nr to arm_arch_timer.h, and add enum spi_nr.
> Add arm_arch_timer get ppi from DT and GTDT support for kvm.
>
> v2: https://lkml.org/lkml/2015/12/2/10
> Rebase to latest kernel version(4.4-rc3).
> Fix the bug about the config problem,
> use CONFIG_ACPI_GTDT instead of CONFIG_ACPI in arm_arch_timer.c
>
> v1: The first upstreaming version: https://lkml.org/lkml/2015/10/28/553
>
> Fu Wei (9):
> clocksource/drivers/arm_arch_timer: Move enums and defines to header
> file
> clocksource/drivers/arm_arch_timer: Add a new enum for spi type
> clocksource/drivers/arm_arch_timer: Improve printk relevant code
> acpi/arm64: Add GTDT table parse driver
> clocksource/drivers/arm_arch_timer: Simplify ACPI support code.
> acpi/arm64: Add memory-mapped timer support in GTDT driver
> clocksource/drivers/arm_arch_timer: Refactor the timer init code to
> prepare for GTDT
> clocksource/drivers/arm_arch_timer: Add GTDT support for memory-mapped
> timer
> acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
>
> arch/arm64/Kconfig | 1 +
> drivers/acpi/arm64/Kconfig | 3 +
> drivers/acpi/arm64/Makefile | 1 +
> drivers/acpi/arm64/gtdt.c | 309 ++++++++++++++++++++++++++++++++
> drivers/clocksource/Kconfig | 2 +-
> drivers/clocksource/arm_arch_timer.c | 331 +++++++++++++++++++++--------------
> drivers/watchdog/Kconfig | 1 +
> include/clocksource/arm_arch_timer.h | 32 ++++
> include/linux/acpi.h | 7 +
> 9 files changed, 558 insertions(+), 129 deletions(-)
> create mode 100644 drivers/acpi/arm64/gtdt.c
>
^ permalink raw reply
* [PATCH 2/3] arm64: dump: Make the page table dumping seq_file optional
From: Mark Rutland @ 2016-09-30 0:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160929213257.30505-3-labbott@redhat.com>
On Thu, Sep 29, 2016 at 02:32:56PM -0700, Laura Abbott wrote:
> The page table dumping code always assumes it will be dumping to a
> seq_file to userspace. The dumping code is useful in other situations.
> Let the seq_file be optional.
>
> Signed-off-by: Laura Abbott <labbott@redhat.com>
It might be worth elaborating on those other situations, e.g. that for those
we'll have some additional logic that will only run in the absence of a
seq_file.
The NOPing out of logic in the !seq_file case does feel a bit like spaghetti
code, but it's not obvious to me that adding finer-grained callbacks is much
better, and I guess we can reconsider that if and when we need to add more
logic.
Regardless of the above:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Thanks,
Mark.
> ---
> arch/arm64/mm/dump.c | 26 +++++++++++++++++++-------
> 1 file changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
> index 29e0838..e318f3d 100644
> --- a/arch/arm64/mm/dump.c
> +++ b/arch/arm64/mm/dump.c
> @@ -50,6 +50,18 @@ static const struct addr_marker address_markers[] = {
> { -1, NULL },
> };
>
> +#define pt_dump_seq_printf(m, fmt, args...) \
> +({ \
> + if (m) \
> + seq_printf(m, fmt, ##args); \
> +})
> +
> +#define pt_dump_seq_puts(m, fmt) \
> +({ \
> + if (m) \
> + seq_printf(m, fmt); \
> +})
> +
> /*
> * The page dumper groups page table entries of the same type into a single
> * description. It uses pg_state to track the range information while
> @@ -186,7 +198,7 @@ static void dump_prot(struct pg_state *st, const struct prot_bits *bits,
> s = bits->clear;
>
> if (s)
> - seq_printf(st->seq, " %s", s);
> + pt_dump_seq_printf(st->seq, " %s", s);
> }
> }
>
> @@ -200,14 +212,14 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
> st->level = level;
> st->current_prot = prot;
> st->start_address = addr;
> - seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
> + pt_dump_seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
> } else if (prot != st->current_prot || level != st->level ||
> addr >= st->marker[1].start_address) {
> const char *unit = units;
> unsigned long delta;
>
> if (st->current_prot) {
> - seq_printf(st->seq, "0x%016lx-0x%016lx ",
> + pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx ",
> st->start_address, addr);
>
> delta = (addr - st->start_address) >> 10;
> @@ -215,17 +227,17 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
> delta >>= 10;
> unit++;
> }
> - seq_printf(st->seq, "%9lu%c %s", delta, *unit,
> + pt_dump_seq_printf(st->seq, "%9lu%c %s", delta, *unit,
> pg_level[st->level].name);
> if (pg_level[st->level].bits)
> dump_prot(st, pg_level[st->level].bits,
> pg_level[st->level].num);
> - seq_puts(st->seq, "\n");
> + pt_dump_seq_puts(st->seq, "\n");
> }
>
> if (addr >= st->marker[1].start_address) {
> st->marker++;
> - seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
> + pt_dump_seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
> }
>
> st->start_address = addr;
> @@ -235,7 +247,7 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
>
> if (addr >= st->marker[1].start_address) {
> st->marker++;
> - seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
> + pt_dump_seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
> }
>
> }
> --
> 2.10.0
>
^ permalink raw reply
* [PATCH 1/3] arm64: dump: Make ptdump debugfs a separate option
From: Laura Abbott @ 2016-09-30 0:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160930001339.GA4369@remoulade>
On 09/29/2016 05:13 PM, Mark Rutland wrote:
> Hi,
>
> On Thu, Sep 29, 2016 at 02:32:55PM -0700, Laura Abbott wrote:
>> ptdump_register currently initializes a set of page table information and
>> registers debugfs. There are uses for the ptdump option without wanting the
>> debugfs options. Split this out to make it a separate option.
>>
>> Signed-off-by: Laura Abbott <labbott@redhat.com>
>> ---
>> arch/arm64/Kconfig.debug | 6 +++++-
>> arch/arm64/include/asm/ptdump.h | 15 +++++++++++++--
>> arch/arm64/mm/Makefile | 3 ++-
>> arch/arm64/mm/dump.c | 30 +++++++++---------------------
>> arch/arm64/mm/ptdump_debugfs.c | 33 +++++++++++++++++++++++++++++++++
>> 5 files changed, 62 insertions(+), 25 deletions(-)
>> create mode 100644 arch/arm64/mm/ptdump_debugfs.c
>
> As a heads-up, Ard has new ARM64_PTUMP user under drivers/firmware/efi queued
> up in the EFI tree, which will also need fixing up. See commit d80448ac92b72051
> ("efi/arm64: Add debugfs node to dump UEFI runtime page tables") [1].
>
> [...]
>
I'll take a look at that, thanks for the pointer!
>> +#include <linux/seq_file.h>
>> #include <linux/mm_types.h>
>
> Nit: please keep headers in alphabetical order.
>
>> -static void walk_pgd(struct pg_state *st, struct mm_struct *mm,
>> +static void __walk_pgd(struct pg_state *st, struct mm_struct *mm,
>
> Can we leave this name as-is? We didn't change walk_{pud,pmd,pte}, so this is
> inconsistent, and we haven't reused the name.
>
Yes, I think this is a relic of earlier refactoring attempts.
> [...]
>
>> +int ptdump_register(struct ptdump_info *info, const char *name)
>> +{
>> + ptdump_initialize(info);
>> + return ptdump_debugfs_create(info, name);
>> }
>
> It feels like a layering violation to have the core ptdump code call the
> debugfs ptdump code. Is there some reason this has to live here?
>
Which 'this' are you referring to here? Are you suggesting moving
the ptdump_register elsewhere or moving the debugfs create elsewhere?
> Other than the above points, this looks good to me.
>
> Thanks,
> Mark.
>
> [1] https://git.kernel.org/cgit/linux/kernel/git/mfleming/efi.git/commit/?h=next&id=9d80448ac92b720512c415265597d349d8b5c3e8
>
^ permalink raw reply
* [PATCH 1/3] arm64: dump: Make ptdump debugfs a separate option
From: Mark Rutland @ 2016-09-30 0:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160929213257.30505-2-labbott@redhat.com>
Hi,
On Thu, Sep 29, 2016 at 02:32:55PM -0700, Laura Abbott wrote:
> ptdump_register currently initializes a set of page table information and
> registers debugfs. There are uses for the ptdump option without wanting the
> debugfs options. Split this out to make it a separate option.
>
> Signed-off-by: Laura Abbott <labbott@redhat.com>
> ---
> arch/arm64/Kconfig.debug | 6 +++++-
> arch/arm64/include/asm/ptdump.h | 15 +++++++++++++--
> arch/arm64/mm/Makefile | 3 ++-
> arch/arm64/mm/dump.c | 30 +++++++++---------------------
> arch/arm64/mm/ptdump_debugfs.c | 33 +++++++++++++++++++++++++++++++++
> 5 files changed, 62 insertions(+), 25 deletions(-)
> create mode 100644 arch/arm64/mm/ptdump_debugfs.c
As a heads-up, Ard has new ARM64_PTUMP user under drivers/firmware/efi queued
up in the EFI tree, which will also need fixing up. See commit d80448ac92b72051
("efi/arm64: Add debugfs node to dump UEFI runtime page tables") [1].
[...]
> +#include <linux/seq_file.h>
> #include <linux/mm_types.h>
Nit: please keep headers in alphabetical order.
> -static void walk_pgd(struct pg_state *st, struct mm_struct *mm,
> +static void __walk_pgd(struct pg_state *st, struct mm_struct *mm,
Can we leave this name as-is? We didn't change walk_{pud,pmd,pte}, so this is
inconsistent, and we haven't reused the name.
[...]
> +int ptdump_register(struct ptdump_info *info, const char *name)
> +{
> + ptdump_initialize(info);
> + return ptdump_debugfs_create(info, name);
> }
It feels like a layering violation to have the core ptdump code call the
debugfs ptdump code. Is there some reason this has to live here?
Other than the above points, this looks good to me.
Thanks,
Mark.
[1] https://git.kernel.org/cgit/linux/kernel/git/mfleming/efi.git/commit/?h=next&id=9d80448ac92b720512c415265597d349d8b5c3e8
^ permalink raw reply
* Crash seen on ARM Juno r1 with 4.8-rc8 when Coresight is enabled
From: Mathieu Poirier @ 2016-09-30 0:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5dc4d096-d580-900c-5750-38e0db1ccbce@arm.com>
On 29 September 2016 at 03:17, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 29/09/16 09:49, Rabin Vincent wrote:
>>
>> On Wed, Sep 28, 2016 at 11:41:41AM -0600, Mathieu Poirier wrote:
>
> [...]
>
>>> Thanks you for reporting this Vankatesh,
>>>
>>> Sudeep and Suzuki, can you guys help me with this - I don't have an R1
>>> to test with.
>>
>>
>> I've seen this too, on other platforms. This should fix it:
>>
>> 8<-----------
>> From a9da7d7b47e67dd6ffcafddadb50e6f97503f296 Mon Sep 17 00:00:00 2001
>> From: Rabin Vincent <rabinv@axis.com>
>> Date: Tue, 30 Aug 2016 08:54:21 +0200
>> Subject: [PATCH] coresight: check for NULL child_name
>>
>> Connection child names associated to ports can sometimes be NULL, which
>> is the case when booting a system on QEMU or when the Coresight power
>> domain isn't switched on. fadf3a44e974 ("coresight: checking for NULL
>> string in coresight_name_match()") fixed one place to handle this but
>> the same check is needed in coresight_orphan_match() to prevent a crash
>> there.
>>
>
> Thanks Rabin, we have exact same fix in linux-next already.
Sorry for the late reply - I am currently travelling.
Sudeep is correct, we have this underway for the 4.9 cycle.
Mathieu
>
> --
> Regards,
> Sudeep
^ permalink raw reply
* [PATCH V2 3/5] PCI: save and restore bus on parent bus reset
From: Sinan Kaya @ 2016-09-29 23:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160929214942.GD20897@localhost>
Hi Bjorn,
On 9/29/2016 5:49 PM, Bjorn Helgaas wrote:
>> + }
> This pattern of "unlock, do something, relock" needs some
> justification. In general it's unsafe because the lock is protecting
> *something*, and you have to assume that something can change as soon
> as you unlock. Maybe you know it's safe in this situation, and if so,
> the explanation of why it's safe is what I'm looking for.
Agreed.
The problem is that save and restore routines obtain the lock again and
they fails as the lock is already held.
The alternative is to change the dev_locks in save and restore to try_lock
so that it will work if locks were previously obtained or not.
>
> Also, you're now calling pci_reset_bridge_secondary_bus() with the dev
> unlocked, where we called it with the dev locked before. Some (but
> worryingly, not all) of the other pci_reset_bridge_secondary_bus()
> callers also have the dev locked. I didn't look long enough to figure
> out if there is a strategy there or if these inconsistencies are
> latent bugs.
>
The goal of this routine is to reset the device not the bridge and the code
will use FLR or others if available. Therefore, it makes perfect sense to
obtain the device lock while doing this.
The code tries to reset the bus if none of the other resets work. This is
where the problem is. It destroys the context for other devices.
I can fix get rid of this unlock, do something and then lock again business
by rewriting the locks in save and restore.
Sinan
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH v2 2/2] drm: zte: add initial vou drm driver
From: Shawn Guo @ 2016-09-29 23:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160925205809.GR20761@phenom.ffwll.local>
On Sun, Sep 25, 2016 at 10:58:09PM +0200, Daniel Vetter wrote:
> On Sat, Sep 24, 2016 at 10:26:25PM +0800, Shawn Guo wrote:
> > It adds the initial ZTE VOU display controller DRM driver. There are
> > still some features to be added, like overlay plane, scaling, and more
> > output devices support. But it's already useful with dual CRTCs and
> > HDMI monitor working.
> >
> > It's been tested on Debian Jessie LXDE desktop with modesetting driver.
> >
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
>
> I've done a very quick read-through, looks real pretty. A few comments
> below and in-line.
Thanks much for looking at it.
> For testing, have you tried to run i-g-t validation tests per our
> documentation? See https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#validating-changes-with-igt
Sorry for my ignorance on that. I'm on business travel right now, and
will give it a try once I get back to the hardware.
> > drivers/gpu/drm/Kconfig | 2 +
> > drivers/gpu/drm/Makefile | 1 +
> > drivers/gpu/drm/zte/Kconfig | 8 +
> > drivers/gpu/drm/zte/Makefile | 8 +
> > drivers/gpu/drm/zte/zx_crtc.c | 691 +++++++++++++++++++++++++++++++++++++++
> > drivers/gpu/drm/zte/zx_crtc.h | 47 +++
> > drivers/gpu/drm/zte/zx_drm_drv.c | 258 +++++++++++++++
> > drivers/gpu/drm/zte/zx_drm_drv.h | 22 ++
> > drivers/gpu/drm/zte/zx_hdmi.c | 540 ++++++++++++++++++++++++++++++
> > drivers/gpu/drm/zte/zx_plane.c | 362 ++++++++++++++++++++
> > drivers/gpu/drm/zte/zx_plane.h | 26 ++
> > 11 files changed, 1965 insertions(+)
> > create mode 100644 drivers/gpu/drm/zte/Kconfig
> > create mode 100644 drivers/gpu/drm/zte/Makefile
> > create mode 100644 drivers/gpu/drm/zte/zx_crtc.c
> > create mode 100644 drivers/gpu/drm/zte/zx_crtc.h
> > create mode 100644 drivers/gpu/drm/zte/zx_drm_drv.c
> > create mode 100644 drivers/gpu/drm/zte/zx_drm_drv.h
> > create mode 100644 drivers/gpu/drm/zte/zx_hdmi.c
> > create mode 100644 drivers/gpu/drm/zte/zx_plane.c
> > create mode 100644 drivers/gpu/drm/zte/zx_plane.h
>
> New entry in MAINTAINERS listening you (and probably dri-devel as the m-l)
> is missing.
Okay. I will add a patch to do that in the next version.
> > +static int zx_drm_bind(struct device *dev)
> > +{
> > + struct drm_device *drm;
> > + struct zx_drm_private *priv;
> > + int ret;
> > +
> > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > + if (!priv)
> > + return -ENOMEM;
> > +
> > + drm = drm_dev_alloc(&zx_drm_driver, dev);
> > + if (!drm)
> > + return -ENOMEM;
> > +
> > + drm->dev_private = priv;
> > + dev_set_drvdata(dev, drm);
> > +
> > + drm_mode_config_init(drm);
> > + drm->mode_config.min_width = 16;
> > + drm->mode_config.min_height = 16;
> > + drm->mode_config.max_width = 4096;
> > + drm->mode_config.max_height = 4096;
> > + drm->mode_config.funcs = &zx_drm_mode_config_funcs;
> > +
> > + ret = drm_dev_register(drm, 0);
>
> drm_dev_register should be the last function call in your bind function.
> Similar for unbind, drm_dev_register should be called first.
>
> As a consequence of that you can remove the drm_connector_(un)register
> calls, those are only needed for hotplugged connectors like dp mst. But
> with correct ordering of drm_dev_(un)register that function will also take
> care of connector registration and unregistration.
Aha, that's the trick to save the call to drm_connector_register() from
connector driver. Thanks for the info.
> > +static int zx_hdmi_get_edid_block(void *data, u8 *buf, unsigned int block,
> > + size_t len)
> > +{
> > + struct zx_hdmi *hdmi = data;
> > + int retry = 0;
> > + int ret = 0;
> > + int i = 0;
> > + u8 val;
> > +
> > + /* Enable DDC master access */
> > + val = hdmi_readb(hdmi, TPI_DDC_MASTER_EN);
> > + val |= HW_DDC_MASTER;
> > + hdmi_writeb(hdmi, TPI_DDC_MASTER_EN, val);
> > +
> > + hdmi_writeb(hdmi, ZX_DDC_ADDR, 0xa0);
> > + hdmi_writeb(hdmi, ZX_DDC_OFFSET, block * EDID_LENGTH);
> > + /* Bits [9:8] of bytes */
> > + hdmi_writeb(hdmi, ZX_DDC_DIN_CNT2, (len >> 8) & 0xff);
> > + /* Bits [7:0] of bytes */
> > + hdmi_writeb(hdmi, ZX_DDC_DIN_CNT1, len & 0xff);
> > +
> > + /* Clear FIFO */
> > + val = hdmi_readb(hdmi, ZX_DDC_CMD);
> > + val &= ~DDC_CMD_MASK;
> > + val |= DDC_CMD_CLEAR_FIFO;
> > + hdmi_writeb(hdmi, ZX_DDC_CMD, val);
> > +
> > + /* Kick off the read */
> > + val = hdmi_readb(hdmi, ZX_DDC_CMD);
> > + val &= ~DDC_CMD_MASK;
> > + val |= DDC_CMD_SEQUENTIAL_READ;
> > + hdmi_writeb(hdmi, ZX_DDC_CMD, val);
>
> It looks like the ZX_DDC register range implements a hw i2c engine (since
> you specifiy port and offsets and everything). Please implement it as an
> i2c_adapter driver and use the normal drm_get_edid function.
Okay. I will give it a try to see if it works.
> > +static int zx_gl_plane_atomic_check(struct drm_plane *plane,
> > + struct drm_plane_state *state)
> > +{
> > + u32 src_w, src_h;
> > +
> > + src_w = state->src_w >> 16;
> > + src_h = state->src_h >> 16;
> > +
> > + /* TODO: support scaling of the plane source */
> > + if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
> > + return -EINVAL;
>
> This is generally not enough checking. You probably need a call to
> drm_plane_helper_check_state.
Okay, will do.
Shawn
^ permalink raw reply
* [PATCH] crypto: arm64/sha256 - add support for SHA256 using NEON instructions
From: Ard Biesheuvel @ 2016-09-29 23:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475189503-9175-2-git-send-email-ard.biesheuvel@linaro.org>
On 29 September 2016 at 15:51, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> This is a port to arm64 of the NEON implementation of SHA256 that lives
> under arch/arm/crypto.
>
> Due to the fact that the AArch64 assembler dialect deviates from the
> 32-bit ARM one in ways that makes sharing code problematic, and given
> that this version only uses the NEON version whereas the original
> implementation supports plain ALU assembler, NEON and Crypto Extensions,
> this code is built from a version sha256-armv4.pl that has been
> transliterated to the AArch64 NEON dialect.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/crypto/Kconfig | 5 +
> arch/arm64/crypto/Makefile | 11 +
> arch/arm64/crypto/sha256-armv4.pl | 413 +++++++++
> arch/arm64/crypto/sha256-core.S_shipped | 883 ++++++++++++++++++++
> arch/arm64/crypto/sha256_neon_glue.c | 103 +++
> 5 files changed, 1415 insertions(+)
>
> diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
> index 2cf32e9887e1..d32371198474 100644
> --- a/arch/arm64/crypto/Kconfig
> +++ b/arch/arm64/crypto/Kconfig
> @@ -18,6 +18,11 @@ config CRYPTO_SHA2_ARM64_CE
> depends on ARM64 && KERNEL_MODE_NEON
> select CRYPTO_HASH
>
> +config CRYPTO_SHA2_ARM64_NEON
> + tristate "SHA-224/SHA-256 digest algorithm (ARMv8 NEON)"
> + depends on ARM64 && KERNEL_MODE_NEON
> + select CRYPTO_HASH
> +
> config CRYPTO_GHASH_ARM64_CE
> tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions"
> depends on ARM64 && KERNEL_MODE_NEON
> diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile
> index abb79b3cfcfe..5156ebee0488 100644
> --- a/arch/arm64/crypto/Makefile
> +++ b/arch/arm64/crypto/Makefile
> @@ -29,6 +29,9 @@ aes-ce-blk-y := aes-glue-ce.o aes-ce.o
> obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o
> aes-neon-blk-y := aes-glue-neon.o aes-neon.o
>
> +obj-$(CONFIG_CRYPTO_SHA2_ARM64_NEON) := sha256-neon.o
There is a typo here that I only spotted just now: this should be += not :=
Herbert, if you're picking this up, could you please fix this at merge
time? Or do you need me to resend?
Thanks,
Ard.
^ permalink raw reply
* [PATCH] clk: bcm2835: Clamp the PLL's requested rate to the hardware limits.
From: Stephen Boyd @ 2016-09-29 23:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160929022334.25537-1-eric@anholt.net>
On 09/28, Eric Anholt wrote:
> Fixes setting low-resolution video modes on HDMI. Now the PLLH_PIX
> divider adjusts itself until the PLLH is within bounds.
>
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
> drivers/clk/bcm/clk-bcm2835.c | 12 +++++-------
> 1 file changed, 5 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
> index 7a7970865c2d..fedc88908e61 100644
> --- a/drivers/clk/bcm/clk-bcm2835.c
> +++ b/drivers/clk/bcm/clk-bcm2835.c
> @@ -499,8 +499,13 @@ static long bcm2835_pll_rate_from_divisors(unsigned long parent_rate,
> static long bcm2835_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> unsigned long *parent_rate)
> {
> + struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
> + const struct bcm2835_pll_data *data = pll->data;
> u32 ndiv, fdiv;
>
> + rate = max(data->min_rate, rate);
> + rate = min(data->max_rate, rate);
clamp() instead?
I wonder if it's worthwhile to do this through clk rate
constraints instead. That's another topic though so this patch is
fine for now.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH] crypto: arm64/sha256 - add support for SHA256 using NEON instructions
From: Ard Biesheuvel @ 2016-09-29 22:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475189503-9175-1-git-send-email-ard.biesheuvel@linaro.org>
This is a port to arm64 of the NEON implementation of SHA256 that lives
under arch/arm/crypto.
Due to the fact that the AArch64 assembler dialect deviates from the
32-bit ARM one in ways that makes sharing code problematic, and given
that this version only uses the NEON version whereas the original
implementation supports plain ALU assembler, NEON and Crypto Extensions,
this code is built from a version sha256-armv4.pl that has been
transliterated to the AArch64 NEON dialect.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/crypto/Kconfig | 5 +
arch/arm64/crypto/Makefile | 11 +
arch/arm64/crypto/sha256-armv4.pl | 413 +++++++++
arch/arm64/crypto/sha256-core.S_shipped | 883 ++++++++++++++++++++
arch/arm64/crypto/sha256_neon_glue.c | 103 +++
5 files changed, 1415 insertions(+)
diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index 2cf32e9887e1..d32371198474 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -18,6 +18,11 @@ config CRYPTO_SHA2_ARM64_CE
depends on ARM64 && KERNEL_MODE_NEON
select CRYPTO_HASH
+config CRYPTO_SHA2_ARM64_NEON
+ tristate "SHA-224/SHA-256 digest algorithm (ARMv8 NEON)"
+ depends on ARM64 && KERNEL_MODE_NEON
+ select CRYPTO_HASH
+
config CRYPTO_GHASH_ARM64_CE
tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions"
depends on ARM64 && KERNEL_MODE_NEON
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile
index abb79b3cfcfe..5156ebee0488 100644
--- a/arch/arm64/crypto/Makefile
+++ b/arch/arm64/crypto/Makefile
@@ -29,6 +29,9 @@ aes-ce-blk-y := aes-glue-ce.o aes-ce.o
obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o
aes-neon-blk-y := aes-glue-neon.o aes-neon.o
+obj-$(CONFIG_CRYPTO_SHA2_ARM64_NEON) := sha256-neon.o
+sha256-neon-y := sha256_neon_glue.o sha256-core.o
+
AFLAGS_aes-ce.o := -DINTERLEAVE=4
AFLAGS_aes-neon.o := -DINTERLEAVE=4
@@ -40,3 +43,11 @@ CFLAGS_crc32-arm64.o := -mcpu=generic+crc
$(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE
$(call if_changed_rule,cc_o_c)
+
+quiet_cmd_perl = PERL $@
+ cmd_perl = $(PERL) $(<) > $(@)
+
+$(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
+ $(call cmd,perl)
+
+.PRECIOUS: $(obj)/sha256-core.S
diff --git a/arch/arm64/crypto/sha256-armv4.pl b/arch/arm64/crypto/sha256-armv4.pl
new file mode 100644
index 000000000000..9ff788339b1c
--- /dev/null
+++ b/arch/arm64/crypto/sha256-armv4.pl
@@ -0,0 +1,413 @@
+#!/usr/bin/env perl
+
+#
+# AArch64 port of the OpenSSL SHA256 implementation for ARM NEON
+#
+# Copyright (c) 2016 Linaro Ltd. <ard.biesheuvel@linaro.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+#
+# Permission to use under GPL terms is granted.
+# ====================================================================
+
+# SHA256 block procedure for ARMv4. May 2007.
+
+# Performance is ~2x better than gcc 3.4 generated code and in "abso-
+# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
+# byte [on single-issue Xscale PXA250 core].
+
+# July 2010.
+#
+# Rescheduling for dual-issue pipeline resulted in 22% improvement on
+# Cortex A8 core and ~20 cycles per processed byte.
+
+# February 2011.
+#
+# Profiler-assisted and platform-specific optimization resulted in 16%
+# improvement on Cortex A8 core and ~15.4 cycles per processed byte.
+
+# September 2013.
+#
+# Add NEON implementation. On Cortex A8 it was measured to process one
+# byte in 12.5 cycles or 23% faster than integer-only code. Snapdragon
+# S4 does it in 12.5 cycles too, but it's 50% faster than integer-only
+# code (meaning that latter performs sub-optimally, nothing was done
+# about it).
+
+# May 2014.
+#
+# Add ARMv8 code path performing at 2.0 cpb on Apple A7.
+
+while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+open STDOUT,">$output";
+
+$ctx="x0"; $t0="w0"; $xt0="x0";
+$inp="x1"; $t4="w1"; $xt4="x1";
+$len="x2"; $t1="w2"; $xt1="x2";
+ $t3="w3";
+$A="w4";
+$B="w5";
+$C="w6";
+$D="w7";
+$E="w8";
+$F="w9";
+$G="w10";
+$H="w11";
+ at V=($A,$B,$C,$D,$E,$F,$G,$H);
+$t2="w12";
+$xt2="x12";
+$Ktbl="x14";
+
+ at Sigma0=( 2,13,22);
+ at Sigma1=( 6,11,25);
+ at sigma0=( 7,18, 3);
+ at sigma1=(17,19,10);
+
+######################################################################
+# NEON stuff
+#
+{{{
+my @VB=map("v$_.16b",(0..3));
+my @VS=map("v$_.4s",(0..3));
+
+my ($TS0,$TS1,$TS2,$TS3,$TS4,$TS5,$TS6,$TS7)=("v4.4s","v5.4s","v6.4s","v7.4s","v8.4s","v9.4s","v10.4s","v11.4s");
+my ($TB0,$TB1,$TB2,$TB3,$TB4,$TB5,$TB6,$TB7)=("v4.16b","v5.16b","v6.16b","v7.16b","v8.16b","v9.16b","v10.16b","v11.16b");
+my ($TD5HI,$TD5LO,$TD7LO)=("v9.d[1]", "d9", "v11.d[0]");
+my $Xfer=$xt4;
+my $j=0;
+
+sub AUTOLOAD() # thunk [simplified] x86-style perlasm
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
+ my $arg = pop;
+ $arg = "#$arg" if ($arg*1 eq $arg);
+ $code .= "\t$opcode\t".join(',', at _,$arg)."\n";
+}
+
+sub Xupdate()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body);
+ my ($a,$b,$c,$d,$e,$f,$g,$h);
+
+ &ext ($TB0, at VB[0], at VB[1],4); # X[1..4]
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ext ($TB1, at VB[2], at VB[3],4); # X[9..12]
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS2,$TS0,$sigma0[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &add (@VS[0], at VS[0],$TS1); # X[0..3] += X[9..12]
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS1,$TS0,$sigma0[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &sli ($TS2,$TS0,32-$sigma0[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS3,$TS0,$sigma0[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &eor ($TB1,$TB1,$TB2);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &sli ($TS3,$TS0,32-$sigma0[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS4, at VS[3],$sigma1[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &eor ($TB1,$TB1,$TB3); # sigma0(X[1..4])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &sli ($TS4, at VS[3],32-$sigma1[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS5, at VS[3],$sigma1[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &add (@VS[0], at VS[0],$TS1); # X[0..3] += sigma0(X[1..4])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &eor ($TB5,$TB5,$TB4);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS4, at VS[3],$sigma1[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &sli ($TS4, at VS[3],32-$sigma1[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &eor ($TB5,$TB5,$TB4); # sigma1(X[14..15])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &mov ($TD5LO, $TD5HI);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &add (@VS[0], at VS[0],$TS5); # X[0..1] += sigma1(X[14..15])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS6, at VS[0],$sigma1[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &sli ($TS6, at VS[0],32-$sigma1[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS7, at VS[0],$sigma1[2]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &eor ($TB7,$TB7,$TB6);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ushr ($TS6, at VS[0],$sigma1[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ld1 ("{$TS0}","[$Ktbl], #16");
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &sli ($TS6, at VS[0],32-$sigma1[1]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &eor ($TB7,$TB7,$TB6); # sigma1(X[16..17])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &eor ($TB5,$TB5,$TB5);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &mov ($TD5HI, $TD7LO);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &add (@VS[0], at VS[0],$TS5); # X[0..3] += sigma1(X[14..17])
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &add ($TS0,$TS0, at VS[0]);
+ while($#insns>=2) { eval(shift(@insns)); }
+ &st1 ("{$TS0}","[$Xfer], #16");
+ eval(shift(@insns));
+ eval(shift(@insns));
+
+ push(@VB,shift(@VB)); # "rotate" X[]
+ push(@VS,shift(@VS)); # "rotate" X[]
+}
+
+sub Xpreload()
+{ use integer;
+ my $body = shift;
+ my @insns = (&$body,&$body,&$body,&$body);
+ my ($a,$b,$c,$d,$e,$f,$g,$h);
+
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &ld1 ("{$TS0}","[$Ktbl], #16");
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &rev32 (@VB[0], at VB[0]);
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ eval(shift(@insns));
+ &add ($TS0,$TS0, at VS[0]);
+ foreach (@insns) { eval; } # remaining instructions
+ &st1 ("{$TS0}","[$Xfer], #16");
+
+ push(@VB,shift(@VB)); # "rotate" X[]
+ push(@VS,shift(@VS)); # "rotate" X[]
+}
+
+sub body_00_15 () {
+ (
+ '($a,$b,$c,$d,$e,$f,$g,$h)=@V;'.
+ '&add ($h,$h,$t1)', # h+=X[i]+K[i]
+ '&eor ($t1,$f,$g)',
+ '&eor ($t0,$e,$e,"ror#".($Sigma1[1]-$Sigma1[0]))',
+ '&add ($a,$a,$t2)', # h+=Maj(a,b,c) from the past
+ '&and ($t1,$t1,$e)',
+ '&eor ($t2,$t0,$e,"ror#".($Sigma1[2]-$Sigma1[0]))', # Sigma1(e)
+ '&eor ($t0,$a,$a,"ror#".($Sigma0[1]-$Sigma0[0]))',
+ '&ror ($t2,$t2,"#$Sigma1[0]")',
+ '&eor ($t1,$t1,$g)', # Ch(e,f,g)
+ '&add ($h,$h,$t2)', # h+=Sigma1(e)
+ '&eor ($t2,$a,$b)', # a^b, b^c in next round
+ '&eor ($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))', # Sigma0(a)
+ '&add ($h,$h,$t1)', # h+=Ch(e,f,g)
+ '&ldr ($t1,sprintf "[sp,#%d]",4*(($j+1)&15)) if (($j&15)!=15);'.
+ '&ldr ($t1,"[$Ktbl]") if ($j==15);'.
+ '&ldr ($xt1,"[sp,#64]") if ($j==31)',
+ '&and ($t3,$t3,$t2)', # (b^c)&=(a^b)
+ '&ror ($t0,$t0,"#$Sigma0[0]")',
+ '&add ($d,$d,$h)', # d+=h
+ '&add ($h,$h,$t0);'. # h+=Sigma0(a)
+ '&eor ($t3,$t3,$b)', # Maj(a,b,c)
+ '$j++; unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
+ )
+}
+
+$code.=<<___;
+
+.text
+.type K256,%object
+.align 5
+K256:
+.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size K256,.-K256
+.word 0 // terminator
+
+.global sha256_block_data_order_neon
+.type sha256_block_data_order_neon,%function
+.align 4
+sha256_block_data_order_neon:
+.LNEON:
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ sub sp,sp,#16*4+32
+ adr $Ktbl,K256
+ bic x15,x15,#15 // align for 128-bit stores
+ add $len,$inp,$len,lsl#6 // len to point at the end of inp
+
+ ld1 {@VB[0]},[$inp], #16
+ ld1 {@VB[1]},[$inp], #16
+ ld1 {@VB[2]},[$inp], #16
+ ld1 {@VB[3]},[$inp], #16
+ ld1 {$TS0},[$Ktbl], #16
+ ld1 {$TS1},[$Ktbl], #16
+ ld1 {$TS2},[$Ktbl], #16
+ ld1 {$TS3},[$Ktbl], #16
+ rev32 @VB[0], at VB[0] // yes, even on
+ str $ctx,[sp,#64]
+ rev32 @VB[1], at VB[1] // big-endian
+ str $inp,[sp,#72]
+ mov $Xfer,sp
+ rev32 @VB[2], at VB[2]
+ str $len,[sp,#80]
+ rev32 @VB[3], at VB[3]
+ add $TS0,$TS0, at VS[0]
+ add $TS1,$TS1, at VS[1]
+ st1 {$TS0},[$Xfer], #16
+ add $TS2,$TS2, at VS[2]
+ st1 {$TS1},[$Xfer], #16
+ add $TS3,$TS3, at VS[3]
+ st1 {$TS2-$TS3},[$Xfer], #32
+
+ ldp $A, $B, [$ctx]
+ ldp $C, $D, [$ctx, #8]
+ ldp $E, $F, [$ctx, #16]
+ ldp $G, $H, [$ctx, #24]
+ sub $Xfer,$Xfer,#64
+ ldr $t1,[sp,#0]
+ mov $xt2,xzr
+ eor $t3,$B,$C
+ b .L_00_48
+
+.align 4
+.L_00_48:
+___
+ &Xupdate(\&body_00_15);
+ &Xupdate(\&body_00_15);
+ &Xupdate(\&body_00_15);
+ &Xupdate(\&body_00_15);
+$code.=<<___;
+ cmp $t1,#0 // check for K256 terminator
+ ldr $t1,[sp,#0]
+ sub $Xfer,$Xfer,#64
+ bne .L_00_48
+
+ ldr $inp,[sp,#72]
+ ldr $xt0,[sp,#80]
+ sub $Ktbl,$Ktbl,#256 // rewind $Ktbl
+ cmp $inp,$xt0
+ mov $xt0, #64
+ csel $xt0, $xt0, xzr, eq
+ sub $inp,$inp,$xt0 // avoid SEGV
+ ld1 {@VS[0]},[$inp], #16 // load next input block
+ ld1 {@VS[1]},[$inp], #16
+ ld1 {@VS[2]},[$inp], #16
+ ld1 {@VS[3]},[$inp], #16
+ str $inp,[sp,#72]
+ mov $Xfer,sp
+___
+ &Xpreload(\&body_00_15);
+ &Xpreload(\&body_00_15);
+ &Xpreload(\&body_00_15);
+ &Xpreload(\&body_00_15);
+$code.=<<___;
+ ldr $t0,[$xt1,#0]
+ add $A,$A,$t2 // h+=Maj(a,b,c) from the past
+ ldr $t2,[$xt1,#4]
+ ldr $t3,[$xt1,#8]
+ ldr $t4,[$xt1,#12]
+ add $A,$A,$t0 // accumulate
+ ldr $t0,[$xt1,#16]
+ add $B,$B,$t2
+ ldr $t2,[$xt1,#20]
+ add $C,$C,$t3
+ ldr $t3,[$xt1,#24]
+ add $D,$D,$t4
+ ldr $t4,[$xt1,#28]
+ add $E,$E,$t0
+ str $A,[$xt1],#4
+ add $F,$F,$t2
+ str $B,[$xt1],#4
+ add $G,$G,$t3
+ str $C,[$xt1],#4
+ add $H,$H,$t4
+ str $D,[$xt1],#4
+
+ stp $E, $F, [$xt1]
+ stp $G, $H, [$xt1, #8]
+
+ b.eq 0f
+ mov $Xfer,sp
+ ldr $t1,[sp,#0]
+ eor $t2,$t2,$t2
+ eor $t3,$B,$C
+ b .L_00_48
+
+0: add sp,sp,#16*4+32
+ ldp x29, x30, [sp], #16
+ ret
+
+.size sha256_block_data_order_neon,.-sha256_block_data_order_neon
+___
+}}}
+
+foreach (split($/,$code)) {
+
+ s/\`([^\`]*)\`/eval $1/geo;
+
+ print $_,"\n";
+}
+
+close STDOUT; # enforce flush
+
diff --git a/arch/arm64/crypto/sha256-core.S_shipped b/arch/arm64/crypto/sha256-core.S_shipped
new file mode 100644
index 000000000000..1d9b55367ee0
--- /dev/null
+++ b/arch/arm64/crypto/sha256-core.S_shipped
@@ -0,0 +1,883 @@
+
+.text
+.type K256,%object
+.align 5
+K256:
+.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.size K256,.-K256
+.word 0 // terminator
+
+.global sha256_block_data_order_neon
+.type sha256_block_data_order_neon,%function
+.align 4
+sha256_block_data_order_neon:
+.LNEON:
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ sub sp,sp,#16*4+32
+ adr x14,K256
+ bic x15,x15,#15 // align for 128-bit stores
+ add x2,x1,x2,lsl#6 // len to point at the end of inp
+
+ ld1 {v0.16b},[x1], #16
+ ld1 {v1.16b},[x1], #16
+ ld1 {v2.16b},[x1], #16
+ ld1 {v3.16b},[x1], #16
+ ld1 {v4.4s},[x14], #16
+ ld1 {v5.4s},[x14], #16
+ ld1 {v6.4s},[x14], #16
+ ld1 {v7.4s},[x14], #16
+ rev32 v0.16b,v0.16b // yes, even on
+ str x0,[sp,#64]
+ rev32 v1.16b,v1.16b // big-endian
+ str x1,[sp,#72]
+ mov x1,sp
+ rev32 v2.16b,v2.16b
+ str x2,[sp,#80]
+ rev32 v3.16b,v3.16b
+ add v4.4s,v4.4s,v0.4s
+ add v5.4s,v5.4s,v1.4s
+ st1 {v4.4s},[x1], #16
+ add v6.4s,v6.4s,v2.4s
+ st1 {v5.4s},[x1], #16
+ add v7.4s,v7.4s,v3.4s
+ st1 {v6.4s-v7.4s},[x1], #32
+
+ ldp w4, w5, [x0]
+ ldp w6, w7, [x0, #8]
+ ldp w8, w9, [x0, #16]
+ ldp w10, w11, [x0, #24]
+ sub x1,x1,#64
+ ldr w2,[sp,#0]
+ mov x12,xzr
+ eor w3,w5,w6
+ b .L_00_48
+
+.align 4
+.L_00_48:
+ ext v4.16b,v0.16b,v1.16b,#4
+ add w11,w11,w2
+ eor w2,w9,w10
+ eor w0,w8,w8,ror#5
+ ext v5.16b,v2.16b,v3.16b,#4
+ add w4,w4,w12
+ and w2,w2,w8
+ eor w12,w0,w8,ror#19
+ ushr v6.4s,v4.4s,#7
+ eor w0,w4,w4,ror#11
+ ror w12,w12,#6
+ add v0.4s,v0.4s,v5.4s
+ eor w2,w2,w10
+ add w11,w11,w12
+ ushr v5.4s,v4.4s,#3
+ eor w12,w4,w5
+ eor w0,w0,w4,ror#20
+ sli v6.4s,v4.4s,#25
+ add w11,w11,w2
+ ldr w2,[sp,#4]
+ ushr v7.4s,v4.4s,#18
+ and w3,w3,w12
+ ror w0,w0,#2
+ eor v5.16b,v5.16b,v6.16b
+ add w7,w7,w11
+ add w11,w11,w0
+ eor w3,w3,w5
+ sli v7.4s,v4.4s,#14
+ add w10,w10,w2
+ ushr v8.4s,v3.4s,#17
+ eor w2,w8,w9
+ eor w0,w7,w7,ror#5
+ eor v5.16b,v5.16b,v7.16b
+ add w11,w11,w3
+ and w2,w2,w7
+ sli v8.4s,v3.4s,#15
+ eor w3,w0,w7,ror#19
+ eor w0,w11,w11,ror#11
+ ushr v9.4s,v3.4s,#10
+ ror w3,w3,#6
+ eor w2,w2,w9
+ add v0.4s,v0.4s,v5.4s
+ add w10,w10,w3
+ eor w3,w11,w4
+ eor v9.16b,v9.16b,v8.16b
+ eor w0,w0,w11,ror#20
+ add w10,w10,w2
+ ushr v8.4s,v3.4s,#19
+ ldr w2,[sp,#8]
+ and w12,w12,w3
+ sli v8.4s,v3.4s,#13
+ ror w0,w0,#2
+ add w6,w6,w10
+ eor v9.16b,v9.16b,v8.16b
+ add w10,w10,w0
+ eor w12,w12,w4
+ mov d9,v9.d[1]
+ add w9,w9,w2
+ eor w2,w7,w8
+ add v0.4s,v0.4s,v9.4s
+ eor w0,w6,w6,ror#5
+ add w10,w10,w12
+ ushr v10.4s,v0.4s,#17
+ and w2,w2,w6
+ eor w12,w0,w6,ror#19
+ sli v10.4s,v0.4s,#15
+ eor w0,w10,w10,ror#11
+ ror w12,w12,#6
+ ushr v11.4s,v0.4s,#10
+ eor w2,w2,w8
+ add w9,w9,w12
+ eor v11.16b,v11.16b,v10.16b
+ eor w12,w10,w11
+ eor w0,w0,w10,ror#20
+ ushr v10.4s,v0.4s,#19
+ add w9,w9,w2
+ ldr w2,[sp,#12]
+ ld1 {v4.4s},[x14], #16
+ and w3,w3,w12
+ ror w0,w0,#2
+ sli v10.4s,v0.4s,#13
+ add w5,w5,w9
+ add w9,w9,w0
+ eor w3,w3,w11
+ eor v11.16b,v11.16b,v10.16b
+ add w8,w8,w2
+ eor v9.16b,v9.16b,v9.16b
+ eor w2,w6,w7
+ eor w0,w5,w5,ror#5
+ mov v9.d[1],v11.d[0]
+ add w9,w9,w3
+ and w2,w2,w5
+ add v0.4s,v0.4s,v9.4s
+ eor w3,w0,w5,ror#19
+ eor w0,w9,w9,ror#11
+ add v4.4s,v4.4s,v0.4s
+ ror w3,w3,#6
+ eor w2,w2,w7
+ add w8,w8,w3
+ eor w3,w9,w10
+ eor w0,w0,w9,ror#20
+ add w8,w8,w2
+ ldr w2,[sp,#16]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w4,w4,w8
+ st1 {v4.4s},[x1], #16
+ add w8,w8,w0
+ eor w12,w12,w10
+ ext v4.16b,v1.16b,v2.16b,#4
+ add w7,w7,w2
+ eor w2,w5,w6
+ eor w0,w4,w4,ror#5
+ ext v5.16b,v3.16b,v0.16b,#4
+ add w8,w8,w12
+ and w2,w2,w4
+ eor w12,w0,w4,ror#19
+ ushr v6.4s,v4.4s,#7
+ eor w0,w8,w8,ror#11
+ ror w12,w12,#6
+ add v1.4s,v1.4s,v5.4s
+ eor w2,w2,w6
+ add w7,w7,w12
+ ushr v5.4s,v4.4s,#3
+ eor w12,w8,w9
+ eor w0,w0,w8,ror#20
+ sli v6.4s,v4.4s,#25
+ add w7,w7,w2
+ ldr w2,[sp,#20]
+ ushr v7.4s,v4.4s,#18
+ and w3,w3,w12
+ ror w0,w0,#2
+ eor v5.16b,v5.16b,v6.16b
+ add w11,w11,w7
+ add w7,w7,w0
+ eor w3,w3,w9
+ sli v7.4s,v4.4s,#14
+ add w6,w6,w2
+ ushr v8.4s,v0.4s,#17
+ eor w2,w4,w5
+ eor w0,w11,w11,ror#5
+ eor v5.16b,v5.16b,v7.16b
+ add w7,w7,w3
+ and w2,w2,w11
+ sli v8.4s,v0.4s,#15
+ eor w3,w0,w11,ror#19
+ eor w0,w7,w7,ror#11
+ ushr v9.4s,v0.4s,#10
+ ror w3,w3,#6
+ eor w2,w2,w5
+ add v1.4s,v1.4s,v5.4s
+ add w6,w6,w3
+ eor w3,w7,w8
+ eor v9.16b,v9.16b,v8.16b
+ eor w0,w0,w7,ror#20
+ add w6,w6,w2
+ ushr v8.4s,v0.4s,#19
+ ldr w2,[sp,#24]
+ and w12,w12,w3
+ sli v8.4s,v0.4s,#13
+ ror w0,w0,#2
+ add w10,w10,w6
+ eor v9.16b,v9.16b,v8.16b
+ add w6,w6,w0
+ eor w12,w12,w8
+ mov d9,v9.d[1]
+ add w5,w5,w2
+ eor w2,w11,w4
+ add v1.4s,v1.4s,v9.4s
+ eor w0,w10,w10,ror#5
+ add w6,w6,w12
+ ushr v10.4s,v1.4s,#17
+ and w2,w2,w10
+ eor w12,w0,w10,ror#19
+ sli v10.4s,v1.4s,#15
+ eor w0,w6,w6,ror#11
+ ror w12,w12,#6
+ ushr v11.4s,v1.4s,#10
+ eor w2,w2,w4
+ add w5,w5,w12
+ eor v11.16b,v11.16b,v10.16b
+ eor w12,w6,w7
+ eor w0,w0,w6,ror#20
+ ushr v10.4s,v1.4s,#19
+ add w5,w5,w2
+ ldr w2,[sp,#28]
+ ld1 {v4.4s},[x14], #16
+ and w3,w3,w12
+ ror w0,w0,#2
+ sli v10.4s,v1.4s,#13
+ add w9,w9,w5
+ add w5,w5,w0
+ eor w3,w3,w7
+ eor v11.16b,v11.16b,v10.16b
+ add w4,w4,w2
+ eor v9.16b,v9.16b,v9.16b
+ eor w2,w10,w11
+ eor w0,w9,w9,ror#5
+ mov v9.d[1],v11.d[0]
+ add w5,w5,w3
+ and w2,w2,w9
+ add v1.4s,v1.4s,v9.4s
+ eor w3,w0,w9,ror#19
+ eor w0,w5,w5,ror#11
+ add v4.4s,v4.4s,v1.4s
+ ror w3,w3,#6
+ eor w2,w2,w11
+ add w4,w4,w3
+ eor w3,w5,w6
+ eor w0,w0,w5,ror#20
+ add w4,w4,w2
+ ldr w2,[sp,#32]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w8,w8,w4
+ st1 {v4.4s},[x1], #16
+ add w4,w4,w0
+ eor w12,w12,w6
+ ext v4.16b,v2.16b,v3.16b,#4
+ add w11,w11,w2
+ eor w2,w9,w10
+ eor w0,w8,w8,ror#5
+ ext v5.16b,v0.16b,v1.16b,#4
+ add w4,w4,w12
+ and w2,w2,w8
+ eor w12,w0,w8,ror#19
+ ushr v6.4s,v4.4s,#7
+ eor w0,w4,w4,ror#11
+ ror w12,w12,#6
+ add v2.4s,v2.4s,v5.4s
+ eor w2,w2,w10
+ add w11,w11,w12
+ ushr v5.4s,v4.4s,#3
+ eor w12,w4,w5
+ eor w0,w0,w4,ror#20
+ sli v6.4s,v4.4s,#25
+ add w11,w11,w2
+ ldr w2,[sp,#36]
+ ushr v7.4s,v4.4s,#18
+ and w3,w3,w12
+ ror w0,w0,#2
+ eor v5.16b,v5.16b,v6.16b
+ add w7,w7,w11
+ add w11,w11,w0
+ eor w3,w3,w5
+ sli v7.4s,v4.4s,#14
+ add w10,w10,w2
+ ushr v8.4s,v1.4s,#17
+ eor w2,w8,w9
+ eor w0,w7,w7,ror#5
+ eor v5.16b,v5.16b,v7.16b
+ add w11,w11,w3
+ and w2,w2,w7
+ sli v8.4s,v1.4s,#15
+ eor w3,w0,w7,ror#19
+ eor w0,w11,w11,ror#11
+ ushr v9.4s,v1.4s,#10
+ ror w3,w3,#6
+ eor w2,w2,w9
+ add v2.4s,v2.4s,v5.4s
+ add w10,w10,w3
+ eor w3,w11,w4
+ eor v9.16b,v9.16b,v8.16b
+ eor w0,w0,w11,ror#20
+ add w10,w10,w2
+ ushr v8.4s,v1.4s,#19
+ ldr w2,[sp,#40]
+ and w12,w12,w3
+ sli v8.4s,v1.4s,#13
+ ror w0,w0,#2
+ add w6,w6,w10
+ eor v9.16b,v9.16b,v8.16b
+ add w10,w10,w0
+ eor w12,w12,w4
+ mov d9,v9.d[1]
+ add w9,w9,w2
+ eor w2,w7,w8
+ add v2.4s,v2.4s,v9.4s
+ eor w0,w6,w6,ror#5
+ add w10,w10,w12
+ ushr v10.4s,v2.4s,#17
+ and w2,w2,w6
+ eor w12,w0,w6,ror#19
+ sli v10.4s,v2.4s,#15
+ eor w0,w10,w10,ror#11
+ ror w12,w12,#6
+ ushr v11.4s,v2.4s,#10
+ eor w2,w2,w8
+ add w9,w9,w12
+ eor v11.16b,v11.16b,v10.16b
+ eor w12,w10,w11
+ eor w0,w0,w10,ror#20
+ ushr v10.4s,v2.4s,#19
+ add w9,w9,w2
+ ldr w2,[sp,#44]
+ ld1 {v4.4s},[x14], #16
+ and w3,w3,w12
+ ror w0,w0,#2
+ sli v10.4s,v2.4s,#13
+ add w5,w5,w9
+ add w9,w9,w0
+ eor w3,w3,w11
+ eor v11.16b,v11.16b,v10.16b
+ add w8,w8,w2
+ eor v9.16b,v9.16b,v9.16b
+ eor w2,w6,w7
+ eor w0,w5,w5,ror#5
+ mov v9.d[1],v11.d[0]
+ add w9,w9,w3
+ and w2,w2,w5
+ add v2.4s,v2.4s,v9.4s
+ eor w3,w0,w5,ror#19
+ eor w0,w9,w9,ror#11
+ add v4.4s,v4.4s,v2.4s
+ ror w3,w3,#6
+ eor w2,w2,w7
+ add w8,w8,w3
+ eor w3,w9,w10
+ eor w0,w0,w9,ror#20
+ add w8,w8,w2
+ ldr w2,[sp,#48]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w4,w4,w8
+ st1 {v4.4s},[x1], #16
+ add w8,w8,w0
+ eor w12,w12,w10
+ ext v4.16b,v3.16b,v0.16b,#4
+ add w7,w7,w2
+ eor w2,w5,w6
+ eor w0,w4,w4,ror#5
+ ext v5.16b,v1.16b,v2.16b,#4
+ add w8,w8,w12
+ and w2,w2,w4
+ eor w12,w0,w4,ror#19
+ ushr v6.4s,v4.4s,#7
+ eor w0,w8,w8,ror#11
+ ror w12,w12,#6
+ add v3.4s,v3.4s,v5.4s
+ eor w2,w2,w6
+ add w7,w7,w12
+ ushr v5.4s,v4.4s,#3
+ eor w12,w8,w9
+ eor w0,w0,w8,ror#20
+ sli v6.4s,v4.4s,#25
+ add w7,w7,w2
+ ldr w2,[sp,#52]
+ ushr v7.4s,v4.4s,#18
+ and w3,w3,w12
+ ror w0,w0,#2
+ eor v5.16b,v5.16b,v6.16b
+ add w11,w11,w7
+ add w7,w7,w0
+ eor w3,w3,w9
+ sli v7.4s,v4.4s,#14
+ add w6,w6,w2
+ ushr v8.4s,v2.4s,#17
+ eor w2,w4,w5
+ eor w0,w11,w11,ror#5
+ eor v5.16b,v5.16b,v7.16b
+ add w7,w7,w3
+ and w2,w2,w11
+ sli v8.4s,v2.4s,#15
+ eor w3,w0,w11,ror#19
+ eor w0,w7,w7,ror#11
+ ushr v9.4s,v2.4s,#10
+ ror w3,w3,#6
+ eor w2,w2,w5
+ add v3.4s,v3.4s,v5.4s
+ add w6,w6,w3
+ eor w3,w7,w8
+ eor v9.16b,v9.16b,v8.16b
+ eor w0,w0,w7,ror#20
+ add w6,w6,w2
+ ushr v8.4s,v2.4s,#19
+ ldr w2,[sp,#56]
+ and w12,w12,w3
+ sli v8.4s,v2.4s,#13
+ ror w0,w0,#2
+ add w10,w10,w6
+ eor v9.16b,v9.16b,v8.16b
+ add w6,w6,w0
+ eor w12,w12,w8
+ mov d9,v9.d[1]
+ add w5,w5,w2
+ eor w2,w11,w4
+ add v3.4s,v3.4s,v9.4s
+ eor w0,w10,w10,ror#5
+ add w6,w6,w12
+ ushr v10.4s,v3.4s,#17
+ and w2,w2,w10
+ eor w12,w0,w10,ror#19
+ sli v10.4s,v3.4s,#15
+ eor w0,w6,w6,ror#11
+ ror w12,w12,#6
+ ushr v11.4s,v3.4s,#10
+ eor w2,w2,w4
+ add w5,w5,w12
+ eor v11.16b,v11.16b,v10.16b
+ eor w12,w6,w7
+ eor w0,w0,w6,ror#20
+ ushr v10.4s,v3.4s,#19
+ add w5,w5,w2
+ ldr w2,[sp,#60]
+ ld1 {v4.4s},[x14], #16
+ and w3,w3,w12
+ ror w0,w0,#2
+ sli v10.4s,v3.4s,#13
+ add w9,w9,w5
+ add w5,w5,w0
+ eor w3,w3,w7
+ eor v11.16b,v11.16b,v10.16b
+ add w4,w4,w2
+ eor v9.16b,v9.16b,v9.16b
+ eor w2,w10,w11
+ eor w0,w9,w9,ror#5
+ mov v9.d[1],v11.d[0]
+ add w5,w5,w3
+ and w2,w2,w9
+ add v3.4s,v3.4s,v9.4s
+ eor w3,w0,w9,ror#19
+ eor w0,w5,w5,ror#11
+ add v4.4s,v4.4s,v3.4s
+ ror w3,w3,#6
+ eor w2,w2,w11
+ add w4,w4,w3
+ eor w3,w5,w6
+ eor w0,w0,w5,ror#20
+ add w4,w4,w2
+ ldr w2,[x14]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w8,w8,w4
+ st1 {v4.4s},[x1], #16
+ add w4,w4,w0
+ eor w12,w12,w6
+ cmp w2,#0 // check for K256 terminator
+ ldr w2,[sp,#0]
+ sub x1,x1,#64
+ bne .L_00_48
+
+ ldr x1,[sp,#72]
+ ldr x0,[sp,#80]
+ sub x14,x14,#256 // rewind x14
+ cmp x1,x0
+ mov x0, #64
+ csel x0, x0, xzr, eq
+ sub x1,x1,x0 // avoid SEGV
+ ld1 {v0.4s},[x1], #16 // load next input block
+ ld1 {v1.4s},[x1], #16
+ ld1 {v2.4s},[x1], #16
+ ld1 {v3.4s},[x1], #16
+ str x1,[sp,#72]
+ mov x1,sp
+ add w11,w11,w2
+ eor w2,w9,w10
+ eor w0,w8,w8,ror#5
+ add w4,w4,w12
+ ld1 {v4.4s},[x14], #16
+ and w2,w2,w8
+ eor w12,w0,w8,ror#19
+ eor w0,w4,w4,ror#11
+ ror w12,w12,#6
+ rev32 v0.16b,v0.16b
+ eor w2,w2,w10
+ add w11,w11,w12
+ eor w12,w4,w5
+ eor w0,w0,w4,ror#20
+ add v4.4s,v4.4s,v0.4s
+ add w11,w11,w2
+ ldr w2,[sp,#4]
+ and w3,w3,w12
+ ror w0,w0,#2
+ add w7,w7,w11
+ add w11,w11,w0
+ eor w3,w3,w5
+ add w10,w10,w2
+ eor w2,w8,w9
+ eor w0,w7,w7,ror#5
+ add w11,w11,w3
+ and w2,w2,w7
+ eor w3,w0,w7,ror#19
+ eor w0,w11,w11,ror#11
+ ror w3,w3,#6
+ eor w2,w2,w9
+ add w10,w10,w3
+ eor w3,w11,w4
+ eor w0,w0,w11,ror#20
+ add w10,w10,w2
+ ldr w2,[sp,#8]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w6,w6,w10
+ add w10,w10,w0
+ eor w12,w12,w4
+ add w9,w9,w2
+ eor w2,w7,w8
+ eor w0,w6,w6,ror#5
+ add w10,w10,w12
+ and w2,w2,w6
+ eor w12,w0,w6,ror#19
+ eor w0,w10,w10,ror#11
+ ror w12,w12,#6
+ eor w2,w2,w8
+ add w9,w9,w12
+ eor w12,w10,w11
+ eor w0,w0,w10,ror#20
+ add w9,w9,w2
+ ldr w2,[sp,#12]
+ and w3,w3,w12
+ ror w0,w0,#2
+ add w5,w5,w9
+ add w9,w9,w0
+ eor w3,w3,w11
+ add w8,w8,w2
+ eor w2,w6,w7
+ eor w0,w5,w5,ror#5
+ add w9,w9,w3
+ and w2,w2,w5
+ eor w3,w0,w5,ror#19
+ eor w0,w9,w9,ror#11
+ ror w3,w3,#6
+ eor w2,w2,w7
+ add w8,w8,w3
+ eor w3,w9,w10
+ eor w0,w0,w9,ror#20
+ add w8,w8,w2
+ ldr w2,[sp,#16]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w4,w4,w8
+ add w8,w8,w0
+ eor w12,w12,w10
+ st1 {v4.4s},[x1], #16
+ add w7,w7,w2
+ eor w2,w5,w6
+ eor w0,w4,w4,ror#5
+ add w8,w8,w12
+ ld1 {v4.4s},[x14], #16
+ and w2,w2,w4
+ eor w12,w0,w4,ror#19
+ eor w0,w8,w8,ror#11
+ ror w12,w12,#6
+ rev32 v1.16b,v1.16b
+ eor w2,w2,w6
+ add w7,w7,w12
+ eor w12,w8,w9
+ eor w0,w0,w8,ror#20
+ add v4.4s,v4.4s,v1.4s
+ add w7,w7,w2
+ ldr w2,[sp,#20]
+ and w3,w3,w12
+ ror w0,w0,#2
+ add w11,w11,w7
+ add w7,w7,w0
+ eor w3,w3,w9
+ add w6,w6,w2
+ eor w2,w4,w5
+ eor w0,w11,w11,ror#5
+ add w7,w7,w3
+ and w2,w2,w11
+ eor w3,w0,w11,ror#19
+ eor w0,w7,w7,ror#11
+ ror w3,w3,#6
+ eor w2,w2,w5
+ add w6,w6,w3
+ eor w3,w7,w8
+ eor w0,w0,w7,ror#20
+ add w6,w6,w2
+ ldr w2,[sp,#24]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w10,w10,w6
+ add w6,w6,w0
+ eor w12,w12,w8
+ add w5,w5,w2
+ eor w2,w11,w4
+ eor w0,w10,w10,ror#5
+ add w6,w6,w12
+ and w2,w2,w10
+ eor w12,w0,w10,ror#19
+ eor w0,w6,w6,ror#11
+ ror w12,w12,#6
+ eor w2,w2,w4
+ add w5,w5,w12
+ eor w12,w6,w7
+ eor w0,w0,w6,ror#20
+ add w5,w5,w2
+ ldr w2,[sp,#28]
+ and w3,w3,w12
+ ror w0,w0,#2
+ add w9,w9,w5
+ add w5,w5,w0
+ eor w3,w3,w7
+ add w4,w4,w2
+ eor w2,w10,w11
+ eor w0,w9,w9,ror#5
+ add w5,w5,w3
+ and w2,w2,w9
+ eor w3,w0,w9,ror#19
+ eor w0,w5,w5,ror#11
+ ror w3,w3,#6
+ eor w2,w2,w11
+ add w4,w4,w3
+ eor w3,w5,w6
+ eor w0,w0,w5,ror#20
+ add w4,w4,w2
+ ldr w2,[sp,#32]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w8,w8,w4
+ add w4,w4,w0
+ eor w12,w12,w6
+ st1 {v4.4s},[x1], #16
+ add w11,w11,w2
+ eor w2,w9,w10
+ eor w0,w8,w8,ror#5
+ add w4,w4,w12
+ ld1 {v4.4s},[x14], #16
+ and w2,w2,w8
+ eor w12,w0,w8,ror#19
+ eor w0,w4,w4,ror#11
+ ror w12,w12,#6
+ rev32 v2.16b,v2.16b
+ eor w2,w2,w10
+ add w11,w11,w12
+ eor w12,w4,w5
+ eor w0,w0,w4,ror#20
+ add v4.4s,v4.4s,v2.4s
+ add w11,w11,w2
+ ldr w2,[sp,#36]
+ and w3,w3,w12
+ ror w0,w0,#2
+ add w7,w7,w11
+ add w11,w11,w0
+ eor w3,w3,w5
+ add w10,w10,w2
+ eor w2,w8,w9
+ eor w0,w7,w7,ror#5
+ add w11,w11,w3
+ and w2,w2,w7
+ eor w3,w0,w7,ror#19
+ eor w0,w11,w11,ror#11
+ ror w3,w3,#6
+ eor w2,w2,w9
+ add w10,w10,w3
+ eor w3,w11,w4
+ eor w0,w0,w11,ror#20
+ add w10,w10,w2
+ ldr w2,[sp,#40]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w6,w6,w10
+ add w10,w10,w0
+ eor w12,w12,w4
+ add w9,w9,w2
+ eor w2,w7,w8
+ eor w0,w6,w6,ror#5
+ add w10,w10,w12
+ and w2,w2,w6
+ eor w12,w0,w6,ror#19
+ eor w0,w10,w10,ror#11
+ ror w12,w12,#6
+ eor w2,w2,w8
+ add w9,w9,w12
+ eor w12,w10,w11
+ eor w0,w0,w10,ror#20
+ add w9,w9,w2
+ ldr w2,[sp,#44]
+ and w3,w3,w12
+ ror w0,w0,#2
+ add w5,w5,w9
+ add w9,w9,w0
+ eor w3,w3,w11
+ add w8,w8,w2
+ eor w2,w6,w7
+ eor w0,w5,w5,ror#5
+ add w9,w9,w3
+ and w2,w2,w5
+ eor w3,w0,w5,ror#19
+ eor w0,w9,w9,ror#11
+ ror w3,w3,#6
+ eor w2,w2,w7
+ add w8,w8,w3
+ eor w3,w9,w10
+ eor w0,w0,w9,ror#20
+ add w8,w8,w2
+ ldr w2,[sp,#48]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w4,w4,w8
+ add w8,w8,w0
+ eor w12,w12,w10
+ st1 {v4.4s},[x1], #16
+ add w7,w7,w2
+ eor w2,w5,w6
+ eor w0,w4,w4,ror#5
+ add w8,w8,w12
+ ld1 {v4.4s},[x14], #16
+ and w2,w2,w4
+ eor w12,w0,w4,ror#19
+ eor w0,w8,w8,ror#11
+ ror w12,w12,#6
+ rev32 v3.16b,v3.16b
+ eor w2,w2,w6
+ add w7,w7,w12
+ eor w12,w8,w9
+ eor w0,w0,w8,ror#20
+ add v4.4s,v4.4s,v3.4s
+ add w7,w7,w2
+ ldr w2,[sp,#52]
+ and w3,w3,w12
+ ror w0,w0,#2
+ add w11,w11,w7
+ add w7,w7,w0
+ eor w3,w3,w9
+ add w6,w6,w2
+ eor w2,w4,w5
+ eor w0,w11,w11,ror#5
+ add w7,w7,w3
+ and w2,w2,w11
+ eor w3,w0,w11,ror#19
+ eor w0,w7,w7,ror#11
+ ror w3,w3,#6
+ eor w2,w2,w5
+ add w6,w6,w3
+ eor w3,w7,w8
+ eor w0,w0,w7,ror#20
+ add w6,w6,w2
+ ldr w2,[sp,#56]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w10,w10,w6
+ add w6,w6,w0
+ eor w12,w12,w8
+ add w5,w5,w2
+ eor w2,w11,w4
+ eor w0,w10,w10,ror#5
+ add w6,w6,w12
+ and w2,w2,w10
+ eor w12,w0,w10,ror#19
+ eor w0,w6,w6,ror#11
+ ror w12,w12,#6
+ eor w2,w2,w4
+ add w5,w5,w12
+ eor w12,w6,w7
+ eor w0,w0,w6,ror#20
+ add w5,w5,w2
+ ldr w2,[sp,#60]
+ and w3,w3,w12
+ ror w0,w0,#2
+ add w9,w9,w5
+ add w5,w5,w0
+ eor w3,w3,w7
+ add w4,w4,w2
+ eor w2,w10,w11
+ eor w0,w9,w9,ror#5
+ add w5,w5,w3
+ and w2,w2,w9
+ eor w3,w0,w9,ror#19
+ eor w0,w5,w5,ror#11
+ ror w3,w3,#6
+ eor w2,w2,w11
+ add w4,w4,w3
+ eor w3,w5,w6
+ eor w0,w0,w5,ror#20
+ add w4,w4,w2
+ ldr x2,[sp,#64]
+ and w12,w12,w3
+ ror w0,w0,#2
+ add w8,w8,w4
+ add w4,w4,w0
+ eor w12,w12,w6
+ st1 {v4.4s},[x1], #16
+ ldr w0,[x2,#0]
+ add w4,w4,w12 // h+=Maj(a,b,c) from the past
+ ldr w12,[x2,#4]
+ ldr w3,[x2,#8]
+ ldr w1,[x2,#12]
+ add w4,w4,w0 // accumulate
+ ldr w0,[x2,#16]
+ add w5,w5,w12
+ ldr w12,[x2,#20]
+ add w6,w6,w3
+ ldr w3,[x2,#24]
+ add w7,w7,w1
+ ldr w1,[x2,#28]
+ add w8,w8,w0
+ str w4,[x2],#4
+ add w9,w9,w12
+ str w5,[x2],#4
+ add w10,w10,w3
+ str w6,[x2],#4
+ add w11,w11,w1
+ str w7,[x2],#4
+
+ stp w8, w9, [x2]
+ stp w10, w11, [x2, #8]
+
+ b.eq 0f
+ mov x1,sp
+ ldr w2,[sp,#0]
+ eor w12,w12,w12
+ eor w3,w5,w6
+ b .L_00_48
+
+0: add sp,sp,#16*4+32
+ ldp x29, x30, [sp], #16
+ ret
+
+.size sha256_block_data_order_neon,.-sha256_block_data_order_neon
diff --git a/arch/arm64/crypto/sha256_neon_glue.c b/arch/arm64/crypto/sha256_neon_glue.c
new file mode 100644
index 000000000000..149a4bb869ea
--- /dev/null
+++ b/arch/arm64/crypto/sha256_neon_glue.c
@@ -0,0 +1,103 @@
+/*
+ * AArch64 port of the OpenSSL SHA256 implementation for ARM NEON
+ *
+ * Copyright (c) 2016 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * 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.
+ *
+ */
+
+#include <crypto/internal/hash.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <crypto/sha.h>
+#include <crypto/sha256_base.h>
+#include <asm/neon.h>
+
+MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 NEON");
+MODULE_AUTHOR("Andy Polyakov <appro@openssl.org>");
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL v2");
+
+asmlinkage void sha256_block_data_order_neon(u32 *digest, const void *data,
+ unsigned int num_blks);
+
+static int sha256_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha256_state *sctx = shash_desc_ctx(desc);
+
+ if ((sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE)
+ return crypto_sha256_update(desc, data, len);
+
+ kernel_neon_begin_partial(12);
+ sha256_base_do_update(desc, data, len,
+ (sha256_block_fn *)sha256_block_data_order_neon);
+ kernel_neon_end();
+
+ return 0;
+}
+
+static int sha256_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ kernel_neon_begin_partial(12);
+ if (len)
+ sha256_base_do_update(desc, data, len,
+ (sha256_block_fn *)sha256_block_data_order_neon);
+ sha256_base_do_finalize(desc,
+ (sha256_block_fn *)sha256_block_data_order_neon);
+ kernel_neon_end();
+
+ return sha256_base_finish(desc, out);
+}
+
+static int sha256_final(struct shash_desc *desc, u8 *out)
+{
+ return sha256_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg algs[] = { {
+ .digestsize = SHA256_DIGEST_SIZE,
+ .init = sha256_base_init,
+ .update = sha256_update,
+ .final = sha256_final,
+ .finup = sha256_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base.cra_name = "sha256",
+ .base.cra_driver_name = "sha256-neon",
+ .base.cra_priority = 150,
+ .base.cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .base.cra_blocksize = SHA256_BLOCK_SIZE,
+ .base.cra_module = THIS_MODULE,
+}, {
+ .digestsize = SHA224_DIGEST_SIZE,
+ .init = sha224_base_init,
+ .update = sha256_update,
+ .final = sha256_final,
+ .finup = sha256_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base.cra_name = "sha224",
+ .base.cra_driver_name = "sha224-neon",
+ .base.cra_priority = 150,
+ .base.cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .base.cra_blocksize = SHA224_BLOCK_SIZE,
+ .base.cra_module = THIS_MODULE,
+} };
+
+static int __init sha256_neon_mod_init(void)
+{
+ return crypto_register_shashes(algs, ARRAY_SIZE(algs));
+}
+
+static void __exit sha256_neon_mod_fini(void)
+{
+ crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+}
+
+module_init(sha256_neon_mod_init);
+module_exit(sha256_neon_mod_fini);
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox