* [PATCH 1/3] arm: hisi: add ARCH_MULTI_V5 support
From: Jiancheng Xue @ 2016-11-17 3:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <582C2785.2010804@hisilicon.com>
Hi Wei?
On 2016/11/16 17:31, Wei Xu wrote:
> Hi Pan,
>
> On 2016/11/16 8:56, wenpan wrote:
>> Hi Marty?
>> Does this confict with your patch? If not?I hope this could be merged first. Besides could you tell me the link to your related patch?
>
> This is the link: https://patchwork.kernel.org/patch/9334743/
>
Thank you for offering this.If I want to give some comments on Marty's patch,
what should I do?
For Marty's patch, I think there's no need to add specific config item ARCH_HIxxxx
for every chipset. Some existing chipsets depend on ARCH_HISI directly like Hi3519
and Hi3798CV200. If some options like ARM_GIC is removed from ARCH_HISI, this kind
of chipsets will must choose other place to select it. I suggest we should keep selecting
ARM_GIC under ARCH_HISI as Pan's patch do.
The code may be like this:
config ARCH_HISI
bool "Hisilicon SoC Support"
- depends on ARCH_MULTI_V7
+ depends on ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7
select ARM_AMBA
- select ARM_GIC
+ select ARM_GIC if ARCH_MULTI_V7
+ select ARM_VIC if ARCH_MULTI_V5 || depends on ARCH_MULTI_V6
select ARM_TIMER_SP804
select POWER_RESET
select POWER_RESET_HISI
select POWER_SUPPLY
What's your opinion?
Best Regards,
Jiancheng
>> On 2016/10/17 21:48, Arnd Bergmann wrote:
>>> On Monday, October 17, 2016 8:07:03 PM CEST Pan Wen wrote:
>>>> Add support for some HiSilicon SoCs which depend on ARCH_MULTI_V5.
>>>>
>>>> Signed-off-by: Pan Wen <wenpan@hisilicon.com>
>>>>
>>>
>>> Looks ok. I've added Marty Plummer to Cc, he was recently proposing
>>> patches for Hi3520, which I think is closely related to this one.
>>> Please try to work together so the patches don't conflict. It should
>>> be fairly straightforward since you are basically doing the same
>>> change here.
>>>
^ permalink raw reply
* [PATCH v1 1/4] dt-bindings: Document Broadcom iProc mailbox controller driver
From: Jassi Brar @ 2016-11-17 3:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476817238-1226-2-git-send-email-jonathan.richardson@broadcom.com>
On Wed, Oct 19, 2016 at 12:30 AM, Jonathan Richardson
<jonathan.richardson@broadcom.com> wrote:
> Reviewed-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> Tested-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> Reviewed-by: Vikram Prakash <vikram.prakash@broadcom.com>
> Reviewed-by: Ray Jui <ray.jui@broadcom.com>
> Reviewed-by: Shreesha Rajashekar <shreesha.rajashekar@broadcom.com>
> Reviewed-by: Scott Branden <scott.branden@broadcom.com>
> Signed-off-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> ---
Wow, heavily endorsed! :) Some log explaining the node, would have
been nice. Especially how mailbox acts as an interrupt controller.
Thanks.
^ permalink raw reply
* ILP32 for ARM64 - testing with lmbench
From: Zhangjian (Bamvor) @ 2016-11-17 3:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161028124659.GA24131@yury-N73SV>
Hi, all
I test specint of aarch64 LP64 when aarch32 el0 disable/enabled respectively
and compare with ILP32 unmerged kernel(4.8-rc6) in our arm64 board. I found
that difference(ILP32 disabled/ILP32 unmerged) is bigger when aarch32 el0 is
enabled, compare with aarch32 el0 disabled kernel. And bzip2, mcg, hmmer,
libquantum are the top four differences[1]. Note that bigger is better in
specint test.
In order to make sure the above results, I retest these four testcases in
reportable way(reference the command in the end). The result[2] show that
libquantum decrease -2.09% after ILP32 enabled and aarch32 on. I think it is in
significant.
The result of lmbench is not stable in my board. I plan to dig it later.
[1] The following test result is tested through --size=ref --iterations=3.
1.1 Test when aarch32_el0 is enabled.
ILP32 disabled base line
400.perlbench 100.00% 100%
401.bzip2 99.35% 100%
403.gcc 100.26% 100%
429.mcf 102.75% 100%
445.gobmk 100.00% 100%
456.hmmer 95.66% 100%
458.sjeng 100.00% 100%
462.libquantum 100.00% 100%
471.omnetpp 100.59% 100%
473.astar 99.66% 100%
483.xalancbmk 99.10% 100%
1.2 Test when aarch32_el0 is disabled
ILP32 disabled base line
400.perlbench 100.22% 100%
401.bzip2 100.95% 100%
403.gcc 100.20% 100%
429.mcf 100.76% 100%
445.gobmk 100.36% 100%
456.hmmer 97.94% 100%
458.sjeng 99.73% 100%
462.libquantum 98.72% 100%
471.omnetpp 100.86% 100%
473.astar 99.15% 100%
483.xalancbmk 100.08% 100%
[2] The following test result is tested through: runspec --config=my.cfg --size=test,train,ref --noreportable --tune=base,peak --iterations=3 bzip2 mcf hmmer libquantum
2.1 Test when aarch32_el0 is enabled.
ILP32_enabled base line
401.bzip2 100.82% 100%
429.mcf 100.18% 100%
456.hmmer 99.64% 100%
462.libquantum 97.91% 100%
Regards
Bamvor
On 2016/10/28 20:46, Yury Norov wrote:
> [Add Steve Ellcey, thanks for testing on ThunderX]
>
> Lmbench-3.0-a9 testing is performed on ThunderX machine to check that
> ILP32 series does not add performance regressions for LP64. Test
> summary is in the table below. Our measurements doesn't show
> significant performance regression of LP64 if ILP32 code is merged,
> both enabled or disabled.
>
> ILP32 enabled ILP32 disabled Standard Kernel
> null syscall 0.1066 0.1121 0.1121
> 95.09% 100.00%
>
> stat 1.3947 1.3814 1.3864
> 100.60% 99.64%
>
> fstat 0.4459 0.4344 0.4524
> 98.56% 96.02%
>
> open/close 4.0606 4.0411 4.0453
> 100.38% 99.90%
>
> read 0.4819 0.5014 0.5014
> 96.11% 100.00%
>
> Tested with linux 4.8 because 4.9-rc1 is not fixed yet for ThunderX.
> Other system details below.
>
> Yury.
>
> ubuntu at crb6:~$ uname -a
> Linux crb6 4.8.0+ #3 SMP Thu Oct 27 11:01:32 PDT 2016 aarch64 aarch64 aarch64 GNU/Linux
>
> ubuntu at crb6:~$ cat /proc/meminfo
> MemTotal: 132011948 kB
> MemFree: 131442672 kB
> MemAvailable: 130695764 kB
> Buffers: 15696 kB
> Cached: 88088 kB
> SwapCached: 0 kB
> Active: 82760 kB
> Inactive: 41336 kB
> Active(anon): 20880 kB
> Inactive(anon): 8576 kB
> Active(file): 61880 kB
> Inactive(file): 32760 kB
> Unevictable: 0 kB
> Mlocked: 0 kB
> SwapTotal: 128920572 kB
> SwapFree: 128920572 kB
> Dirty: 0 kB
> Writeback: 0 kB
> AnonPages: 20544 kB
> Mapped: 19780 kB
> Shmem: 9060 kB
> Slab: 78804 kB
> SReclaimable: 27372 kB
> SUnreclaim: 51432 kB
> KernelStack: 8336 kB
> PageTables: 820 kB
> NFS_Unstable: 0 kB
> Bounce: 0 kB
> WritebackTmp: 0 kB
> CommitLimit: 194926544 kB
> Committed_AS: 256324 kB
> VmallocTotal: 135290290112 kB
> VmallocUsed: 0 kB
> VmallocChunk: 0 kB
> AnonHugePages: 0 kB
> ShmemHugePages: 0 kB
> ShmemPmdMapped: 0 kB
> CmaTotal: 0 kB
> CmaFree: 0 kB
> HugePages_Total: 0
> HugePages_Free: 0
> HugePages_Rsvd: 0
> HugePages_Surp: 0
> Hugepagesize: 2048 kB
>
> ubuntu at crb6:~$ cat /proc/cpuinfo
> processor : 0
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 1
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 2
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 3
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 4
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 5
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 6
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 7
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 8
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 9
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 10
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 11
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 12
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 13
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 14
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 15
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 16
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 17
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 18
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 19
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 20
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 21
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 22
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 23
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 24
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 25
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 26
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 27
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 28
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 29
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 30
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 31
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 32
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 33
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 34
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 35
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 36
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 37
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 38
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 39
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 40
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 41
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 42
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 43
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 44
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 45
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 46
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
> processor : 47
> BogoMIPS : 200.00
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
> CPU implementer : 0x43
> CPU architecture: 8
> CPU variant : 0x1
> CPU part : 0x0a1
> CPU revision : 0
>
^ permalink raw reply
* [PATCH v16 00/15] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
From: Xiongfeng Wang @ 2016-11-17 3:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479304148-2965-1-git-send-email-fu.wei@linaro.org>
Tested-by: wangxiongfeng2 at huawei.com on D05 board.
On 2016/11/16 21:48, 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.
> 4. rename some enums and defines, and some cleanups.
> 5. separate out arch_timer_uses_ppi init code and fix a potential bug
> 6. Refactor arch_timer_detect_rate to keep dt code only in *_of_init
> 7. Refactor arch_timer_needs_probing, and call it only if acpi disabled.
> 8. Introduce some new structs and refactor the timer init 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 has been tested on the following platforms with ACPI enabled:
> (1)ARM Foundation v8 model
>
> Changelog:
> v16: https://lkml.org/lkml/2016/
> Fix patchset problem about static enum ppi_nr of 01/13 in v15.
> Refactor arch_timer_detect_rate.
> Refactor arch_timer_needs_probing.
>
> v15: https://lkml.org/lkml/2016/11/15/366
> Re-order patches
> Add arm_arch_timer refactoring patches to prepare for GTDT:
> 1. rename some enums and defines, and some cleanups
> 2. separate out arch_timer_uses_ppi init code and fix a potential bug
> 3. Improve some new structs, refactor the timer init code.
> Since the some structs have been changed, GTDT parser for memory-mapped
> timer and SBSA Generic Watchdog timer have been update.
>
> v14: https://lkml.org/lkml/2016/9/28/573
> 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 (15):
> 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
> clocksource/drivers/arm_arch_timer: rename some enums and defines, and
> some cleanups.
> clocksource/drivers/arm_arch_timer: fix a bug in arch_timer_register
> about arch_timer_uses_ppi
> clocksource/drivers/arm_arch_timer: separate out arch_timer_uses_ppi
> init code to prepare for GTDT.
> clocksource/drivers/arm_arch_timer: Refactor arch_timer_detect_rate to
> keep dt code in *_of_init
> clocksource/drivers/arm_arch_timer: Refactor arch_timer_needs_probing,
> and call it only if acpi disabled.
> clocksource/drivers/arm_arch_timer: Introduce some new structs to
> prepare for GTDT
> clocksource/drivers/arm_arch_timer: Refactor the timer init code to
> prepare for GTDT
> 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: 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 | 411 +++++++++++++++++++++++++++++
> drivers/clocksource/arm_arch_timer.c | 484 ++++++++++++++++++++---------------
> drivers/watchdog/Kconfig | 1 +
> include/clocksource/arm_arch_timer.h | 61 ++++-
> include/linux/acpi.h | 8 +
> virt/kvm/arm/hyp/timer-sr.c | 6 +-
> 9 files changed, 759 insertions(+), 217 deletions(-)
> create mode 100644 drivers/acpi/arm64/gtdt.c
>
^ permalink raw reply
* [PATCH v6 0/3] Add Mediatek JPEG Decoder
From: Rick Chang @ 2016-11-17 3:38 UTC (permalink / raw)
To: linux-arm-kernel
This series of patches provide a v4l2 driver to control Mediatek JPEG decoder
for decoding JPEG image and Motion JPEG bitstream.
changes since v5:
- remove redundant name from struct mtk_jpeg_fmt
- Set state of all buffers to VB2_BUF_STATE_QUEUED if fail in start streaming
- Remove VB2_USERPTR
- Add check for buffer index
changes since v4:
- Change file name of binding documentation
- Revise DT binding documentation
- Revise compatible string
changes since v3:
- Revise DT binding documentation
- Revise compatible string
changes since v2:
- Revise DT binding documentation
changes since v1:
- Rebase for v4.9-rc1.
- Update Compliance test version and result
- Remove redundant path in Makefile
- Fix potential build error without CONFIG_PM_RUNTIME and CONFIG_PM_SLEEP
- Fix warnings from patch check and smatch check
* Dependency
The patch "arm: dts: mt2701: Add node for JPEG decoder" depends on:
CCF "Add clock support for Mediatek MT2701"[1]
iommu and smi "Add the dtsi node of iommu and smi for mt2701"[2]
[1] http://lists.infradead.org/pipermail/linux-mediatek/2016-October/007271.html
[2] https://patchwork.kernel.org/patch/9164013/
* Compliance test
v4l2-compliance SHA : 4ad7174b908a36c4f315e3fe2efa7e2f8a6f375a
Driver Info:
Driver name : mtk-jpeg decode
Card type : mtk-jpeg decoder
Bus info : platform:15004000.jpegdec
Driver version: 4.9.0
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Compliance test for device /dev/video3 (not using libv4l2):
Required ioctls:
test VIDIOC_QUERYCAP: OK
Allow for multiple opens:
test second video open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK
test Scaling: OK
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test VIDIOC_EXPBUF: OK
Test input 0:
Total: 43, Succeeded: 43, Failed: 0, Warnings: 0
Rick Chang (3):
dt-bindings: mediatek: Add a binding for Mediatek JPEG Decoder
vcodec: mediatek: Add Mediatek JPEG Decoder Driver
arm: dts: mt2701: Add node for Mediatek JPEG Decoder
.../bindings/media/mediatek-jpeg-decoder.txt | 37 +
arch/arm/boot/dts/mt2701.dtsi | 14 +
drivers/media/platform/Kconfig | 15 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/mtk-jpeg/Makefile | 2 +
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 1303 ++++++++++++++++++++
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h | 139 +++
drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c | 417 +++++++
drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h | 91 ++
drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c | 160 +++
drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h | 25 +
drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h | 58 +
12 files changed, 2263 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
create mode 100644 drivers/media/platform/mtk-jpeg/Makefile
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h
--
1.9.1
^ permalink raw reply
* [PATCH v6 1/3] dt-bindings: mediatek: Add a binding for Mediatek JPEG Decoder
From: Rick Chang @ 2016-11-17 3:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479353915-5043-1-git-send-email-rick.chang@mediatek.com>
Add a DT binding documentation for Mediatek JPEG Decoder of
MT2701 SoC.
Signed-off-by: Rick Chang <rick.chang@mediatek.com>
Signed-off-by: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../bindings/media/mediatek-jpeg-decoder.txt | 37 ++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
new file mode 100644
index 0000000..3813947
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
@@ -0,0 +1,37 @@
+* Mediatek JPEG Decoder
+
+Mediatek JPEG Decoder is the JPEG decode hardware present in Mediatek SoCs
+
+Required properties:
+- compatible : must be one of the following string:
+ "mediatek,mt8173-jpgdec"
+ "mediatek,mt2701-jpgdec"
+- reg : physical base address of the jpeg decoder registers and length of
+ memory mapped region.
+- interrupts : interrupt number to the interrupt controller.
+- clocks: device clocks, see
+ Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
+- clock-names: must contain "jpgdec-smi" and "jpgdec".
+- power-domains: a phandle to the power domain, see
+ Documentation/devicetree/bindings/power/power_domain.txt for details.
+- mediatek,larb: must contain the local arbiters in the current Socs, see
+ Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+ for details.
+- iommus: should point to the respective IOMMU block with master port as
+ argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
+ for details.
+
+Example:
+ jpegdec: jpegdec at 15004000 {
+ compatible = "mediatek,mt2701-jpgdec";
+ reg = <0 0x15004000 0 0x1000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&imgsys CLK_IMG_JPGDEC_SMI>,
+ <&imgsys CLK_IMG_JPGDEC>;
+ clock-names = "jpgdec-smi",
+ "jpgdec";
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
+ mediatek,larb = <&larb2>;
+ iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
+ <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v6 2/3] vcodec: mediatek: Add Mediatek JPEG Decoder Driver
From: Rick Chang @ 2016-11-17 3:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479353915-5043-1-git-send-email-rick.chang@mediatek.com>
Add v4l2 driver for Mediatek JPEG Decoder
Signed-off-by: Rick Chang <rick.chang@mediatek.com>
Signed-off-by: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
---
drivers/media/platform/Kconfig | 15 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/mtk-jpeg/Makefile | 2 +
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 1303 ++++++++++++++++++++++
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h | 139 +++
drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c | 417 +++++++
drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h | 91 ++
drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c | 160 +++
drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h | 25 +
drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h | 58 +
10 files changed, 2212 insertions(+)
create mode 100644 drivers/media/platform/mtk-jpeg/Makefile
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 754edbf1..96c9887 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -162,6 +162,21 @@ config VIDEO_CODA
Coda is a range of video codec IPs that supports
H.264, MPEG-4, and other video formats.
+config VIDEO_MEDIATEK_JPEG
+ tristate "Mediatek JPEG Codec driver"
+ depends on MTK_IOMMU_V1 || COMPILE_TEST
+ depends on VIDEO_DEV && VIDEO_V4L2
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+ depends on HAS_DMA
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ ---help---
+ Mediatek jpeg codec driver provides HW capability to decode
+ JPEG format
+
+ To compile this driver as a module, choose M here: the
+ module will be called mtk-jpeg
+
config VIDEO_MEDIATEK_VPU
tristate "Mediatek Video Processor Unit"
depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index f842933..cf701e3 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -68,3 +68,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VPU) += mtk-vpu/
obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec/
obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/
+
+obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk-jpeg/
diff --git a/drivers/media/platform/mtk-jpeg/Makefile b/drivers/media/platform/mtk-jpeg/Makefile
new file mode 100644
index 0000000..b2e6069
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/Makefile
@@ -0,0 +1,2 @@
+mtk_jpeg-objs := mtk_jpeg_core.o mtk_jpeg_hw.o mtk_jpeg_parse.o
+obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
new file mode 100644
index 0000000..1101da8
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -0,0 +1,1303 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
+ * Rick Chang <rick.chang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include <soc/mediatek/smi.h>
+#include <asm/dma-iommu.h>
+
+#include "mtk_jpeg_hw.h"
+#include "mtk_jpeg_core.h"
+#include "mtk_jpeg_parse.h"
+
+static struct mtk_jpeg_fmt mtk_jpeg_formats[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_JPEG,
+ .colplanes = 1,
+ .flags = MTK_JPEG_FMT_FLAG_DEC_OUTPUT,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUV420M,
+ .h_sample = {4, 2, 2},
+ .v_sample = {4, 2, 2},
+ .colplanes = 3,
+ .h_align = 5,
+ .v_align = 4,
+ .flags = MTK_JPEG_FMT_FLAG_DEC_CAPTURE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUV422M,
+ .h_sample = {4, 2, 2},
+ .v_sample = {4, 4, 4},
+ .colplanes = 3,
+ .h_align = 5,
+ .v_align = 3,
+ .flags = MTK_JPEG_FMT_FLAG_DEC_CAPTURE,
+ },
+};
+
+#define MTK_JPEG_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_formats)
+
+enum {
+ MTK_JPEG_BUF_FLAGS_INIT = 0,
+ MTK_JPEG_BUF_FLAGS_LAST_FRAME = 1,
+};
+
+struct mtk_jpeg_src_buf {
+ struct vb2_v4l2_buffer b;
+ struct list_head list;
+ int flags;
+ struct mtk_jpeg_dec_param dec_param;
+};
+
+static int debug;
+module_param(debug, int, 0644);
+
+static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh)
+{
+ return container_of(fh, struct mtk_jpeg_ctx, fh);
+}
+
+static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf(
+ struct vb2_buffer *vb)
+{
+ return container_of(to_vb2_v4l2_buffer(vb), struct mtk_jpeg_src_buf, b);
+}
+
+static int mtk_jpeg_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct mtk_jpeg_dev *jpeg = video_drvdata(file);
+
+ strlcpy(cap->driver, MTK_JPEG_NAME " decoder", sizeof(cap->driver));
+ strlcpy(cap->card, MTK_JPEG_NAME " decoder", sizeof(cap->card));
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+ dev_name(jpeg->dev));
+
+ return 0;
+}
+
+static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n,
+ struct v4l2_fmtdesc *f, u32 type)
+{
+ int i, num = 0;
+
+ for (i = 0; i < n; ++i) {
+ if (mtk_jpeg_formats[i].flags & type) {
+ if (num == f->index)
+ break;
+ ++num;
+ }
+ }
+
+ if (i >= n)
+ return -EINVAL;
+
+ f->pixelformat = mtk_jpeg_formats[i].fourcc;
+
+ return 0;
+}
+
+static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return mtk_jpeg_enum_fmt(mtk_jpeg_formats, MTK_JPEG_NUM_FORMATS, f,
+ MTK_JPEG_FMT_FLAG_DEC_CAPTURE);
+}
+
+static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return mtk_jpeg_enum_fmt(mtk_jpeg_formats, MTK_JPEG_NUM_FORMATS, f,
+ MTK_JPEG_FMT_FLAG_DEC_OUTPUT);
+}
+
+static struct mtk_jpeg_q_data *mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ return &ctx->out_q;
+ return &ctx->cap_q;
+}
+
+static struct mtk_jpeg_fmt *mtk_jpeg_find_format(struct mtk_jpeg_ctx *ctx,
+ u32 pixelformat,
+ unsigned int fmt_type)
+{
+ unsigned int k, fmt_flag;
+
+ fmt_flag = (fmt_type == MTK_JPEG_FMT_TYPE_OUTPUT) ?
+ MTK_JPEG_FMT_FLAG_DEC_OUTPUT :
+ MTK_JPEG_FMT_FLAG_DEC_CAPTURE;
+
+ for (k = 0; k < MTK_JPEG_NUM_FORMATS; k++) {
+ struct mtk_jpeg_fmt *fmt = &mtk_jpeg_formats[k];
+
+ if (fmt->fourcc == pixelformat && fmt->flags & fmt_flag)
+ return fmt;
+ }
+
+ return NULL;
+}
+
+static void mtk_jpeg_bound_align_image(u32 *w, unsigned int wmin,
+ unsigned int wmax, unsigned int walign,
+ u32 *h, unsigned int hmin,
+ unsigned int hmax, unsigned int halign)
+{
+ int width, height, w_step, h_step;
+
+ width = *w;
+ height = *h;
+ w_step = 1 << walign;
+ h_step = 1 << halign;
+
+ v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
+ if (*w < width && (*w + w_step) <= wmax)
+ *w += w_step;
+ if (*h < height && (*h + h_step) <= hmax)
+ *h += h_step;
+}
+
+static void mtk_jpeg_adjust_fmt_mplane(struct mtk_jpeg_ctx *ctx,
+ struct v4l2_format *f)
+{
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct mtk_jpeg_q_data *q_data;
+ int i;
+
+ q_data = mtk_jpeg_get_q_data(ctx, f->type);
+
+ pix_mp->width = q_data->w;
+ pix_mp->height = q_data->h;
+ pix_mp->pixelformat = q_data->fmt->fourcc;
+ pix_mp->num_planes = q_data->fmt->colplanes;
+
+ for (i = 0; i < pix_mp->num_planes; i++) {
+ pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i];
+ pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
+ }
+}
+
+static int mtk_jpeg_try_fmt_mplane(struct v4l2_format *f,
+ struct mtk_jpeg_fmt *fmt,
+ struct mtk_jpeg_ctx *ctx, int q_type)
+{
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ int i;
+
+ memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
+ pix_mp->field = V4L2_FIELD_NONE;
+
+ if (ctx->state != MTK_JPEG_INIT) {
+ mtk_jpeg_adjust_fmt_mplane(ctx, f);
+ goto end;
+ }
+
+ pix_mp->num_planes = fmt->colplanes;
+ pix_mp->pixelformat = fmt->fourcc;
+
+ if (q_type == MTK_JPEG_FMT_TYPE_OUTPUT) {
+ struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0];
+
+ mtk_jpeg_bound_align_image(&pix_mp->width, MTK_JPEG_MIN_WIDTH,
+ MTK_JPEG_MAX_WIDTH, 0,
+ &pix_mp->height, MTK_JPEG_MIN_HEIGHT,
+ MTK_JPEG_MAX_HEIGHT, 0);
+
+ memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
+ pfmt->bytesperline = 0;
+ /* Source size must be aligned to 128 */
+ pfmt->sizeimage = mtk_jpeg_align(pfmt->sizeimage, 128);
+ if (pfmt->sizeimage == 0)
+ pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE;
+ goto end;
+ }
+
+ /* type is MTK_JPEG_FMT_TYPE_CAPTURE */
+ mtk_jpeg_bound_align_image(&pix_mp->width, MTK_JPEG_MIN_WIDTH,
+ MTK_JPEG_MAX_WIDTH, fmt->h_align,
+ &pix_mp->height, MTK_JPEG_MIN_HEIGHT,
+ MTK_JPEG_MAX_HEIGHT, fmt->v_align);
+
+ for (i = 0; i < fmt->colplanes; i++) {
+ struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
+ u32 stride = pix_mp->width * fmt->h_sample[i] / 4;
+ u32 h = pix_mp->height * fmt->v_sample[i] / 4;
+
+ memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
+ pfmt->bytesperline = stride;
+ pfmt->sizeimage = stride * h;
+ }
+end:
+ v4l2_dbg(2, debug, &jpeg->v4l2_dev, "wxh:%ux%u\n",
+ pix_mp->width, pix_mp->height);
+ for (i = 0; i < pix_mp->num_planes; i++) {
+ v4l2_dbg(2, debug, &jpeg->v4l2_dev,
+ "plane[%d] bpl=%u, size=%u\n",
+ i,
+ pix_mp->plane_fmt[i].bytesperline,
+ pix_mp->plane_fmt[i].sizeimage);
+ }
+ return 0;
+}
+
+static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct vb2_queue *vq;
+ struct mtk_jpeg_q_data *q_data = NULL;
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ int i;
+
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = mtk_jpeg_get_q_data(ctx, f->type);
+
+ memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
+ pix_mp->width = q_data->w;
+ pix_mp->height = q_data->h;
+ pix_mp->field = V4L2_FIELD_NONE;
+ pix_mp->pixelformat = q_data->fmt->fourcc;
+ pix_mp->num_planes = q_data->fmt->colplanes;
+ pix_mp->colorspace = ctx->colorspace;
+ pix_mp->ycbcr_enc = ctx->ycbcr_enc;
+ pix_mp->xfer_func = ctx->xfer_func;
+ pix_mp->quantization = ctx->quantization;
+
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) g_fmt:%c%c%c%c wxh:%ux%u\n",
+ f->type,
+ (pix_mp->pixelformat & 0xff),
+ (pix_mp->pixelformat >> 8 & 0xff),
+ (pix_mp->pixelformat >> 16 & 0xff),
+ (pix_mp->pixelformat >> 24 & 0xff),
+ pix_mp->width, pix_mp->height);
+
+ for (i = 0; i < pix_mp->num_planes; i++) {
+ struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
+
+ pfmt->bytesperline = q_data->bytesperline[i];
+ pfmt->sizeimage = q_data->sizeimage[i];
+ memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
+
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev,
+ "plane[%d] bpl=%u, size=%u\n",
+ i,
+ pfmt->bytesperline,
+ pfmt->sizeimage);
+ }
+ return 0;
+}
+
+static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_fmt *fmt;
+
+ fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat,
+ MTK_JPEG_FMT_TYPE_CAPTURE);
+ if (!fmt)
+ fmt = ctx->cap_q.fmt;
+
+ v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
+ f->type,
+ (fmt->fourcc & 0xff),
+ (fmt->fourcc >> 8 & 0xff),
+ (fmt->fourcc >> 16 & 0xff),
+ (fmt->fourcc >> 24 & 0xff));
+
+ return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_CAPTURE);
+}
+
+static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_fmt *fmt;
+
+ fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat,
+ MTK_JPEG_FMT_TYPE_OUTPUT);
+ if (!fmt)
+ fmt = ctx->out_q.fmt;
+
+ v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
+ f->type,
+ (fmt->fourcc & 0xff),
+ (fmt->fourcc >> 8 & 0xff),
+ (fmt->fourcc >> 16 & 0xff),
+ (fmt->fourcc >> 24 & 0xff));
+
+ return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_OUTPUT);
+}
+
+static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx,
+ struct v4l2_format *f)
+{
+ struct vb2_queue *vq;
+ struct mtk_jpeg_q_data *q_data = NULL;
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ unsigned int f_type;
+ int i;
+
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = mtk_jpeg_get_q_data(ctx, f->type);
+
+ if (vb2_is_busy(vq)) {
+ v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
+ return -EBUSY;
+ }
+
+ f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
+ MTK_JPEG_FMT_TYPE_OUTPUT : MTK_JPEG_FMT_TYPE_CAPTURE;
+
+ q_data->fmt = mtk_jpeg_find_format(ctx, pix_mp->pixelformat, f_type);
+ q_data->w = pix_mp->width;
+ q_data->h = pix_mp->height;
+ ctx->colorspace = pix_mp->colorspace;
+ ctx->ycbcr_enc = pix_mp->ycbcr_enc;
+ ctx->xfer_func = pix_mp->xfer_func;
+ ctx->quantization = pix_mp->quantization;
+
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) s_fmt:%c%c%c%c wxh:%ux%u\n",
+ f->type,
+ (q_data->fmt->fourcc & 0xff),
+ (q_data->fmt->fourcc >> 8 & 0xff),
+ (q_data->fmt->fourcc >> 16 & 0xff),
+ (q_data->fmt->fourcc >> 24 & 0xff),
+ q_data->w, q_data->h);
+
+ for (i = 0; i < q_data->fmt->colplanes; i++) {
+ q_data->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
+ q_data->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
+
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev,
+ "plane[%d] bpl=%u, size=%u\n",
+ i, q_data->bytesperline[i], q_data->sizeimage[i]);
+ }
+
+ return 0;
+}
+
+static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+
+ ret = mtk_jpeg_try_fmt_vid_out_mplane(file, priv, f);
+ if (ret)
+ return ret;
+
+ return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f);
+}
+
+static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+
+ ret = mtk_jpeg_try_fmt_vid_cap_mplane(file, priv, f);
+ if (ret)
+ return ret;
+
+ return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f);
+}
+
+static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx)
+{
+ static const struct v4l2_event ev_src_ch = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ .u.src_change.changes =
+ V4L2_EVENT_SRC_CH_RESOLUTION,
+ };
+
+ v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
+}
+
+static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int mtk_jpeg_g_selection(struct file *file, void *priv,
+ struct v4l2_selection *s)
+{
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_COMPOSE:
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ s->r.width = ctx->out_q.w;
+ s->r.height = ctx->out_q.h;
+ s->r.left = 0;
+ s->r.top = 0;
+ break;
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ case V4L2_SEL_TGT_COMPOSE_PADDED:
+ s->r.width = ctx->cap_q.w;
+ s->r.height = ctx->cap_q.h;
+ s->r.left = 0;
+ s->r.top = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int mtk_jpeg_s_selection(struct file *file, void *priv,
+ struct v4l2_selection *s)
+{
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_COMPOSE:
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = ctx->out_q.w;
+ s->r.height = ctx->out_q.h;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct v4l2_fh *fh = file->private_data;
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct vb2_queue *vq;
+ struct vb2_buffer *vb;
+ struct mtk_jpeg_src_buf *jpeg_src_buf;
+
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ goto end;
+
+ vq = v4l2_m2m_get_vq(fh->m2m_ctx, buf->type);
+ if (buf->index >= vq->num_buffers) {
+ dev_err(ctx->jpeg->dev, "buffer index out of range\n");
+ return -EINVAL;
+ }
+
+ vb = vq->bufs[buf->index];
+ jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
+ jpeg_src_buf->flags = (buf->m.planes[0].bytesused == 0) ?
+ MTK_JPEG_BUF_FLAGS_LAST_FRAME : MTK_JPEG_BUF_FLAGS_INIT;
+end:
+ return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
+}
+
+static const struct v4l2_ioctl_ops mtk_jpeg_ioctl_ops = {
+ .vidioc_querycap = mtk_jpeg_querycap,
+ .vidioc_enum_fmt_vid_cap_mplane = mtk_jpeg_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_out_mplane = mtk_jpeg_enum_fmt_vid_out,
+ .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane,
+ .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane,
+ .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane,
+ .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane,
+ .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane,
+ .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane,
+ .vidioc_qbuf = mtk_jpeg_qbuf,
+ .vidioc_subscribe_event = mtk_jpeg_subscribe_event,
+ .vidioc_g_selection = mtk_jpeg_g_selection,
+ .vidioc_s_selection = mtk_jpeg_s_selection,
+
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static int mtk_jpeg_queue_setup(struct vb2_queue *q,
+ unsigned int *num_buffers,
+ unsigned int *num_planes,
+ unsigned int sizes[],
+ struct device *alloc_ctxs[])
+{
+ struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+ struct mtk_jpeg_q_data *q_data = NULL;
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ int i;
+
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) buf_req count=%u\n",
+ q->type, *num_buffers);
+
+ q_data = mtk_jpeg_get_q_data(ctx, q->type);
+ if (!q_data)
+ return -EINVAL;
+
+ *num_planes = q_data->fmt->colplanes;
+ for (i = 0; i < q_data->fmt->colplanes; i++) {
+ sizes[i] = q_data->sizeimage[i];
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev, "sizeimage[%d]=%u\n",
+ i, sizes[i]);
+ }
+
+ return 0;
+}
+
+static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
+{
+ struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct mtk_jpeg_q_data *q_data = NULL;
+ int i;
+
+ q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type);
+ if (!q_data)
+ return -EINVAL;
+
+ for (i = 0; i < q_data->fmt->colplanes; i++)
+ vb2_set_plane_payload(vb, i, q_data->sizeimage[i]);
+
+ return 0;
+}
+
+static bool mtk_jpeg_check_resolution_change(struct mtk_jpeg_ctx *ctx,
+ struct mtk_jpeg_dec_param *param)
+{
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ struct mtk_jpeg_q_data *q_data;
+
+ q_data = &ctx->out_q;
+ if (q_data->w != param->pic_w || q_data->h != param->pic_h) {
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev, "Picture size change\n");
+ return true;
+ }
+
+ q_data = &ctx->cap_q;
+ if (q_data->fmt != mtk_jpeg_find_format(ctx, param->dst_fourcc,
+ MTK_JPEG_FMT_TYPE_CAPTURE)) {
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev, "format change\n");
+ return true;
+ }
+ return false;
+}
+
+static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx,
+ struct mtk_jpeg_dec_param *param)
+{
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ struct mtk_jpeg_q_data *q_data;
+ int i;
+
+ q_data = &ctx->out_q;
+ q_data->w = param->pic_w;
+ q_data->h = param->pic_h;
+
+ q_data = &ctx->cap_q;
+ q_data->w = param->dec_w;
+ q_data->h = param->dec_h;
+ q_data->fmt = mtk_jpeg_find_format(ctx,
+ param->dst_fourcc,
+ MTK_JPEG_FMT_TYPE_CAPTURE);
+
+ for (i = 0; i < q_data->fmt->colplanes; i++) {
+ q_data->bytesperline[i] = param->mem_stride[i];
+ q_data->sizeimage[i] = param->comp_size[i];
+ }
+
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev,
+ "set_parse cap:%c%c%c%c pic(%u, %u), buf(%u, %u)\n",
+ (param->dst_fourcc & 0xff),
+ (param->dst_fourcc >> 8 & 0xff),
+ (param->dst_fourcc >> 16 & 0xff),
+ (param->dst_fourcc >> 24 & 0xff),
+ param->pic_w, param->pic_h,
+ param->dec_w, param->dec_h);
+}
+
+static void mtk_jpeg_buf_queue(struct vb2_buffer *vb)
+{
+ struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct mtk_jpeg_dec_param *param;
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ struct mtk_jpeg_src_buf *jpeg_src_buf;
+ bool header_valid;
+
+ v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
+ vb->vb2_queue->type, vb->index, vb);
+
+ if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ goto end;
+
+ jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
+ param = &jpeg_src_buf->dec_param;
+ memset(param, 0, sizeof(*param));
+
+ if (jpeg_src_buf->flags & MTK_JPEG_BUF_FLAGS_LAST_FRAME) {
+ v4l2_dbg(1, debug, &jpeg->v4l2_dev, "Got eos\n");
+ goto end;
+ }
+ header_valid = mtk_jpeg_parse(param, (u8 *)vb2_plane_vaddr(vb, 0),
+ vb2_get_plane_payload(vb, 0));
+ if (!header_valid) {
+ v4l2_err(&jpeg->v4l2_dev, "Header invalid.\n");
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+ return;
+ }
+
+ if (ctx->state == MTK_JPEG_INIT) {
+ mtk_jpeg_queue_src_chg_event(ctx);
+ mtk_jpeg_set_queue_data(ctx, param);
+ ctx->state = MTK_JPEG_RUNNING;
+ }
+end:
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
+}
+
+static void *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ return v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ else
+ return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+}
+
+static int mtk_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+ struct vb2_buffer *vb;
+ int ret = 0;
+
+ ret = pm_runtime_get_sync(ctx->jpeg->dev);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+err:
+ while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_QUEUED);
+ return ret;
+}
+
+static void mtk_jpeg_stop_streaming(struct vb2_queue *q)
+{
+ struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+ struct vb2_buffer *vb;
+
+ /*
+ * STREAMOFF is an acknowledgment for source change event.
+ * Before STREAMOFF, we still have to return the old resolution and
+ * subsampling. Update capture queue when the stream is off.
+ */
+ if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
+ !V4L2_TYPE_IS_OUTPUT(q->type)) {
+ struct mtk_jpeg_src_buf *src_buf;
+
+ vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
+ mtk_jpeg_set_queue_data(ctx, &src_buf->dec_param);
+ ctx->state = MTK_JPEG_RUNNING;
+ } else if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+ ctx->state = MTK_JPEG_INIT;
+ }
+
+ while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_ERROR);
+
+ pm_runtime_put_sync(ctx->jpeg->dev);
+}
+
+static struct vb2_ops mtk_jpeg_qops = {
+ .queue_setup = mtk_jpeg_queue_setup,
+ .buf_prepare = mtk_jpeg_buf_prepare,
+ .buf_queue = mtk_jpeg_buf_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = mtk_jpeg_start_streaming,
+ .stop_streaming = mtk_jpeg_stop_streaming,
+};
+
+static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx,
+ struct vb2_buffer *src_buf,
+ struct mtk_jpeg_bs *bs)
+{
+ bs->str_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+ bs->end_addr = bs->str_addr +
+ mtk_jpeg_align(vb2_get_plane_payload(src_buf, 0), 16);
+ bs->size = mtk_jpeg_align(vb2_plane_size(src_buf, 0), 128);
+}
+
+static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx,
+ struct mtk_jpeg_dec_param *param,
+ struct vb2_buffer *dst_buf,
+ struct mtk_jpeg_fb *fb)
+{
+ int i;
+
+ if (param->comp_num != dst_buf->num_planes) {
+ dev_err(ctx->jpeg->dev, "plane number mismatch (%u != %u)\n",
+ param->comp_num, dst_buf->num_planes);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < dst_buf->num_planes; i++) {
+ if (vb2_plane_size(dst_buf, i) < param->comp_size[i]) {
+ dev_err(ctx->jpeg->dev,
+ "buffer size is underflow (%lu < %u)\n",
+ vb2_plane_size(dst_buf, 0),
+ param->comp_size[i]);
+ return -EINVAL;
+ }
+ fb->plane_addr[i] = vb2_dma_contig_plane_dma_addr(dst_buf, i);
+ }
+
+ return 0;
+}
+
+static void mtk_jpeg_device_run(void *priv)
+{
+ struct mtk_jpeg_ctx *ctx = priv;
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ struct vb2_buffer *src_buf, *dst_buf;
+ enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
+ unsigned long flags;
+ struct mtk_jpeg_src_buf *jpeg_src_buf;
+ struct mtk_jpeg_bs bs;
+ struct mtk_jpeg_fb fb;
+ int i;
+
+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+ jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(src_buf);
+
+ if (jpeg_src_buf->flags & MTK_JPEG_BUF_FLAGS_LAST_FRAME) {
+ for (i = 0; i < dst_buf->num_planes; i++)
+ vb2_set_plane_payload(dst_buf, i, 0);
+ buf_state = VB2_BUF_STATE_DONE;
+ goto dec_end;
+ }
+
+ if (mtk_jpeg_check_resolution_change(ctx, &jpeg_src_buf->dec_param)) {
+ mtk_jpeg_queue_src_chg_event(ctx);
+ ctx->state = MTK_JPEG_SOURCE_CHANGE;
+ v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
+ return;
+ }
+
+ mtk_jpeg_set_dec_src(ctx, src_buf, &bs);
+ if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, dst_buf, &fb))
+ goto dec_end;
+
+ spin_lock_irqsave(&jpeg->hw_lock, flags);
+ mtk_jpeg_dec_reset(jpeg->dec_reg_base);
+ mtk_jpeg_dec_set_config(jpeg->dec_reg_base,
+ &jpeg_src_buf->dec_param, &bs, &fb);
+
+ mtk_jpeg_dec_start(jpeg->dec_reg_base);
+ spin_unlock_irqrestore(&jpeg->hw_lock, flags);
+ return;
+
+dec_end:
+ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), buf_state);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), buf_state);
+ v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
+}
+
+static int mtk_jpeg_job_ready(void *priv)
+{
+ struct mtk_jpeg_ctx *ctx = priv;
+
+ return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0;
+}
+
+static void mtk_jpeg_job_abort(void *priv)
+{
+ struct mtk_jpeg_ctx *ctx = priv;
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
+ struct vb2_buffer *src_buf, *dst_buf;
+
+ src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), VB2_BUF_STATE_ERROR);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), VB2_BUF_STATE_ERROR);
+ v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
+}
+
+static struct v4l2_m2m_ops mtk_jpeg_m2m_ops = {
+ .device_run = mtk_jpeg_device_run,
+ .job_ready = mtk_jpeg_job_ready,
+ .job_abort = mtk_jpeg_job_abort,
+};
+
+static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct mtk_jpeg_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
+ src_vq->drv_priv = ctx;
+ src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
+ src_vq->ops = &mtk_jpeg_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->lock = &ctx->jpeg->lock;
+ src_vq->dev = ctx->jpeg->dev;
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
+ dst_vq->drv_priv = ctx;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->ops = &mtk_jpeg_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->lock = &ctx->jpeg->lock;
+ dst_vq->dev = ctx->jpeg->dev;
+ ret = vb2_queue_init(dst_vq);
+
+ return ret;
+}
+
+static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
+{
+ int ret;
+
+ ret = mtk_smi_larb_get(jpeg->larb);
+ if (ret)
+ dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret);
+ clk_prepare_enable(jpeg->clk_jdec_smi);
+ clk_prepare_enable(jpeg->clk_jdec);
+}
+
+static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
+{
+ clk_disable_unprepare(jpeg->clk_jdec);
+ clk_disable_unprepare(jpeg->clk_jdec_smi);
+ mtk_smi_larb_put(jpeg->larb);
+}
+
+static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
+{
+ struct mtk_jpeg_dev *jpeg = priv;
+ struct mtk_jpeg_ctx *ctx;
+ struct vb2_buffer *src_buf, *dst_buf;
+ struct mtk_jpeg_src_buf *jpeg_src_buf;
+ enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
+ u32 dec_irq_ret;
+ u32 dec_ret;
+ int i;
+
+ ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+ if (!ctx) {
+ v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
+ return IRQ_HANDLED;
+ }
+
+ src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(src_buf);
+
+ dec_ret = mtk_jpeg_dec_get_int_status(jpeg->dec_reg_base);
+ dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret);
+
+ if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW)
+ mtk_jpeg_dec_reset(jpeg->dec_reg_base);
+
+ if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) {
+ dev_err(jpeg->dev, "decode failed\n");
+ goto dec_end;
+ }
+
+ for (i = 0; i < dst_buf->num_planes; i++)
+ vb2_set_plane_payload(dst_buf, i,
+ jpeg_src_buf->dec_param.comp_size[i]);
+
+ buf_state = VB2_BUF_STATE_DONE;
+
+dec_end:
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), buf_state);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), buf_state);
+ v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
+ return IRQ_HANDLED;
+}
+
+static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx)
+{
+ struct mtk_jpeg_q_data *q = &ctx->out_q;
+ int i;
+
+ ctx->colorspace = V4L2_COLORSPACE_JPEG,
+ ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
+ ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+
+ q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
+ MTK_JPEG_FMT_TYPE_OUTPUT);
+ q->w = MTK_JPEG_MIN_WIDTH;
+ q->h = MTK_JPEG_MIN_HEIGHT;
+ q->bytesperline[0] = 0;
+ q->sizeimage[0] = MTK_JPEG_DEFAULT_SIZEIMAGE;
+
+ q = &ctx->cap_q;
+ q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_YUV420M,
+ MTK_JPEG_FMT_TYPE_CAPTURE);
+ q->w = MTK_JPEG_MIN_WIDTH;
+ q->h = MTK_JPEG_MIN_HEIGHT;
+
+ for (i = 0; i < q->fmt->colplanes; i++) {
+ u32 stride = q->w * q->fmt->h_sample[i] / 4;
+ u32 h = q->h * q->fmt->v_sample[i] / 4;
+
+ q->bytesperline[i] = stride;
+ q->sizeimage[i] = stride * h;
+ }
+}
+
+static int mtk_jpeg_open(struct file *file)
+{
+ struct mtk_jpeg_dev *jpeg = video_drvdata(file);
+ struct video_device *vfd = video_devdata(file);
+ struct mtk_jpeg_ctx *ctx;
+ int ret = 0;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ if (mutex_lock_interruptible(&jpeg->lock)) {
+ ret = -ERESTARTSYS;
+ goto free;
+ }
+
+ v4l2_fh_init(&ctx->fh, vfd);
+ file->private_data = &ctx->fh;
+ v4l2_fh_add(&ctx->fh);
+
+ ctx->jpeg = jpeg;
+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx,
+ mtk_jpeg_queue_init);
+ if (IS_ERR(ctx->fh.m2m_ctx)) {
+ ret = PTR_ERR(ctx->fh.m2m_ctx);
+ goto error;
+ }
+
+ mtk_jpeg_set_default_params(ctx);
+ mutex_unlock(&jpeg->lock);
+ return 0;
+
+error:
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ mutex_unlock(&jpeg->lock);
+free:
+ kfree(ctx);
+ return ret;
+}
+
+static int mtk_jpeg_release(struct file *file)
+{
+ struct mtk_jpeg_dev *jpeg = video_drvdata(file);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(file->private_data);
+
+ mutex_lock(&jpeg->lock);
+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ kfree(ctx);
+ mutex_unlock(&jpeg->lock);
+ return 0;
+}
+
+static const struct v4l2_file_operations mtk_jpeg_fops = {
+ .owner = THIS_MODULE,
+ .open = mtk_jpeg_open,
+ .release = mtk_jpeg_release,
+ .poll = v4l2_m2m_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = v4l2_m2m_fop_mmap,
+};
+
+static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
+{
+ struct device_node *node;
+ struct platform_device *pdev;
+
+ node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0);
+ if (!node)
+ return -EINVAL;
+ pdev = of_find_device_by_node(node);
+ if (WARN_ON(!pdev)) {
+ of_node_put(node);
+ return -EINVAL;
+ }
+ of_node_put(node);
+
+ jpeg->larb = &pdev->dev;
+
+ jpeg->clk_jdec = devm_clk_get(jpeg->dev, "jpgdec");
+ if (IS_ERR(jpeg->clk_jdec))
+ return -EINVAL;
+
+ jpeg->clk_jdec_smi = devm_clk_get(jpeg->dev, "jpgdec-smi");
+ if (IS_ERR(jpeg->clk_jdec_smi))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mtk_jpeg_probe(struct platform_device *pdev)
+{
+ struct mtk_jpeg_dev *jpeg;
+ struct resource *res;
+ int dec_irq;
+ int ret;
+
+ jpeg = devm_kzalloc(&pdev->dev, sizeof(*jpeg), GFP_KERNEL);
+ if (!jpeg)
+ return -ENOMEM;
+
+ mutex_init(&jpeg->lock);
+ spin_lock_init(&jpeg->hw_lock);
+ jpeg->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ jpeg->dec_reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(jpeg->dec_reg_base)) {
+ ret = PTR_ERR(jpeg->dec_reg_base);
+ return ret;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ dec_irq = platform_get_irq(pdev, 0);
+ if (!res || dec_irq < 0) {
+ dev_err(&pdev->dev, "Failed to get dec_irq %d.\n", dec_irq);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = devm_request_irq(&pdev->dev, dec_irq, mtk_jpeg_dec_irq, 0,
+ pdev->name, jpeg);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to request dec_irq %d (%d)\n",
+ dec_irq, ret);
+ ret = -EINVAL;
+ goto err_req_irq;
+ }
+
+ ret = mtk_jpeg_clk_init(jpeg);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to init clk, err %d\n", ret);
+ goto err_clk_init;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register v4l2 device\n");
+ ret = -EINVAL;
+ goto err_dev_register;
+ }
+
+ jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_m2m_ops);
+ if (IS_ERR(jpeg->m2m_dev)) {
+ v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
+ ret = PTR_ERR(jpeg->m2m_dev);
+ goto err_m2m_init;
+ }
+
+ jpeg->dec_vdev = video_device_alloc();
+ if (!jpeg->dec_vdev) {
+ ret = -ENOMEM;
+ goto err_dec_vdev_alloc;
+ }
+ snprintf(jpeg->dec_vdev->name, sizeof(jpeg->dec_vdev->name),
+ "%s-dec", MTK_JPEG_NAME);
+ jpeg->dec_vdev->fops = &mtk_jpeg_fops;
+ jpeg->dec_vdev->ioctl_ops = &mtk_jpeg_ioctl_ops;
+ jpeg->dec_vdev->minor = -1;
+ jpeg->dec_vdev->release = video_device_release;
+ jpeg->dec_vdev->lock = &jpeg->lock;
+ jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev;
+ jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
+ jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
+ V4L2_CAP_VIDEO_M2M_MPLANE;
+
+ ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_GRABBER, 3);
+ if (ret) {
+ v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
+ goto err_dec_vdev_register;
+ }
+
+ video_set_drvdata(jpeg->dec_vdev, jpeg);
+ v4l2_info(&jpeg->v4l2_dev,
+ "decoder device registered as /dev/video%d (%d,%d)\n",
+ jpeg->dec_vdev->num, VIDEO_MAJOR, jpeg->dec_vdev->minor);
+
+ platform_set_drvdata(pdev, jpeg);
+
+ pm_runtime_enable(&pdev->dev);
+
+ return 0;
+
+err_dec_vdev_register:
+ video_device_release(jpeg->dec_vdev);
+
+err_dec_vdev_alloc:
+ v4l2_m2m_release(jpeg->m2m_dev);
+
+err_m2m_init:
+ v4l2_device_unregister(&jpeg->v4l2_dev);
+
+err_dev_register:
+
+err_clk_init:
+
+err_req_irq:
+
+ return ret;
+}
+
+static int mtk_jpeg_remove(struct platform_device *pdev)
+{
+ struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev);
+
+ pm_runtime_disable(&pdev->dev);
+ video_unregister_device(jpeg->dec_vdev);
+ video_device_release(jpeg->dec_vdev);
+ v4l2_m2m_release(jpeg->m2m_dev);
+ v4l2_device_unregister(&jpeg->v4l2_dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mtk_jpeg_pm_suspend(struct device *dev)
+{
+ struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
+
+ mtk_jpeg_dec_reset(jpeg->dec_reg_base);
+ mtk_jpeg_clk_off(jpeg);
+
+ return 0;
+}
+
+static int mtk_jpeg_pm_resume(struct device *dev)
+{
+ struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
+
+ mtk_jpeg_clk_on(jpeg);
+ mtk_jpeg_dec_reset(jpeg->dec_reg_base);
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_jpeg_suspend(struct device *dev)
+{
+ int ret;
+
+ if (pm_runtime_suspended(dev))
+ return 0;
+
+ ret = mtk_jpeg_pm_suspend(dev);
+ return ret;
+}
+
+static int mtk_jpeg_resume(struct device *dev)
+{
+ int ret;
+
+ if (pm_runtime_suspended(dev))
+ return 0;
+
+ ret = mtk_jpeg_pm_resume(dev);
+
+ return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops mtk_jpeg_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mtk_jpeg_suspend, mtk_jpeg_resume)
+ SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL)
+};
+
+static const struct of_device_id mtk_jpeg_match[] = {
+ {
+ .compatible = "mediatek,mt8173-jpgdec",
+ .data = NULL,
+ },
+ {
+ .compatible = "mediatek,mt2701-jpgdec",
+ .data = NULL,
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_jpeg_match);
+
+static struct platform_driver mtk_jpeg_driver = {
+ .probe = mtk_jpeg_probe,
+ .remove = mtk_jpeg_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = MTK_JPEG_NAME,
+ .of_match_table = mtk_jpeg_match,
+ .pm = &mtk_jpeg_pm_ops,
+ },
+};
+
+module_platform_driver(mtk_jpeg_driver);
+
+MODULE_DESCRIPTION("MediaTek JPEG codec driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
new file mode 100644
index 0000000..1a6cdfd
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
+ * Rick Chang <rick.chang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MTK_JPEG_CORE_H
+#define _MTK_JPEG_CORE_H
+
+#include <linux/interrupt.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fh.h>
+
+#define MTK_JPEG_NAME "mtk-jpeg"
+
+#define MTK_JPEG_FMT_FLAG_DEC_OUTPUT BIT(0)
+#define MTK_JPEG_FMT_FLAG_DEC_CAPTURE BIT(1)
+
+#define MTK_JPEG_FMT_TYPE_OUTPUT 1
+#define MTK_JPEG_FMT_TYPE_CAPTURE 2
+
+#define MTK_JPEG_MIN_WIDTH 32
+#define MTK_JPEG_MIN_HEIGHT 32
+#define MTK_JPEG_MAX_WIDTH 8192
+#define MTK_JPEG_MAX_HEIGHT 8192
+
+#define MTK_JPEG_DEFAULT_SIZEIMAGE (1 * 1024 * 1024)
+
+enum mtk_jpeg_ctx_state {
+ MTK_JPEG_INIT = 0,
+ MTK_JPEG_RUNNING,
+ MTK_JPEG_SOURCE_CHANGE,
+};
+
+/**
+ * struct mt_jpeg - JPEG IP abstraction
+ * @lock: the mutex protecting this structure
+ * @hw_lock: spinlock protecting the hw device resource
+ * @workqueue: decode work queue
+ * @dev: JPEG device
+ * @v4l2_dev: v4l2 device for mem2mem mode
+ * @m2m_dev: v4l2 mem2mem device data
+ * @alloc_ctx: videobuf2 memory allocator's context
+ * @dec_vdev: video device node for decoder mem2mem mode
+ * @dec_reg_base: JPEG registers mapping
+ * @clk_jdec: JPEG hw working clock
+ * @clk_jdec_smi: JPEG SMI bus clock
+ * @larb: SMI device
+ */
+struct mtk_jpeg_dev {
+ struct mutex lock;
+ spinlock_t hw_lock;
+ struct workqueue_struct *workqueue;
+ struct device *dev;
+ struct v4l2_device v4l2_dev;
+ struct v4l2_m2m_dev *m2m_dev;
+ void *alloc_ctx;
+ struct video_device *dec_vdev;
+ void __iomem *dec_reg_base;
+ struct clk *clk_jdec;
+ struct clk *clk_jdec_smi;
+ struct device *larb;
+};
+
+/**
+ * struct jpeg_fmt - driver's internal color format data
+ * @fourcc: the fourcc code, 0 if not applicable
+ * @h_sample: horizontal sample count of plane in 4 * 4 pixel image
+ * @v_sample: vertical sample count of plane in 4 * 4 pixel image
+ * @colplanes: number of color planes (1 for packed formats)
+ * @h_align: horizontal alignment order (align to 2^h_align)
+ * @v_align: vertical alignment order (align to 2^v_align)
+ * @flags: flags describing format applicability
+ */
+struct mtk_jpeg_fmt {
+ u32 fourcc;
+ int h_sample[VIDEO_MAX_PLANES];
+ int v_sample[VIDEO_MAX_PLANES];
+ int colplanes;
+ int h_align;
+ int v_align;
+ u32 flags;
+};
+
+/**
+ * mtk_jpeg_q_data - parameters of one queue
+ * @fmt: driver-specific format of this queue
+ * @w: image width
+ * @h: image height
+ * @bytesperline: distance in bytes between the leftmost pixels in two adjacent
+ * lines
+ * @sizeimage: image buffer size in bytes
+ */
+struct mtk_jpeg_q_data {
+ struct mtk_jpeg_fmt *fmt;
+ u32 w;
+ u32 h;
+ u32 bytesperline[VIDEO_MAX_PLANES];
+ u32 sizeimage[VIDEO_MAX_PLANES];
+};
+
+/**
+ * mtk_jpeg_ctx - the device context data
+ * @jpeg: JPEG IP device for this context
+ * @out_q: source (output) queue information
+ * @cap_q: destination (capture) queue queue information
+ * @fh: V4L2 file handle
+ * @dec_param parameters for HW decoding
+ * @state: state of the context
+ * @header_valid: set if header has been parsed and valid
+ * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
+ * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
+ * @quantization: enum v4l2_quantization, colorspace quantization
+ * @xfer_func: enum v4l2_xfer_func, colorspace transfer function
+ */
+struct mtk_jpeg_ctx {
+ struct mtk_jpeg_dev *jpeg;
+ struct mtk_jpeg_q_data out_q;
+ struct mtk_jpeg_q_data cap_q;
+ struct v4l2_fh fh;
+ enum mtk_jpeg_ctx_state state;
+
+ enum v4l2_colorspace colorspace;
+ enum v4l2_ycbcr_encoding ycbcr_enc;
+ enum v4l2_quantization quantization;
+ enum v4l2_xfer_func xfer_func;
+};
+
+#endif /* _MTK_JPEG_CORE_H */
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c
new file mode 100644
index 0000000..77b4cc6
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
+ * Rick Chang <rick.chang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <media/videobuf2-core.h>
+
+#include "mtk_jpeg_hw.h"
+
+#define MTK_JPEG_DUNUM_MASK(val) (((val) - 1) & 0x3)
+
+enum mtk_jpeg_color {
+ MTK_JPEG_COLOR_420 = 0x00221111,
+ MTK_JPEG_COLOR_422 = 0x00211111,
+ MTK_JPEG_COLOR_444 = 0x00111111,
+ MTK_JPEG_COLOR_422V = 0x00121111,
+ MTK_JPEG_COLOR_422X2 = 0x00412121,
+ MTK_JPEG_COLOR_422VX2 = 0x00222121,
+ MTK_JPEG_COLOR_400 = 0x00110000
+};
+
+static inline int mtk_jpeg_verify_align(u32 val, int align, u32 reg)
+{
+ if (val & (align - 1)) {
+ pr_err("mtk-jpeg: write reg %x without %d align\n", reg, align);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mtk_jpeg_decide_format(struct mtk_jpeg_dec_param *param)
+{
+ param->src_color = (param->sampling_w[0] << 20) |
+ (param->sampling_h[0] << 16) |
+ (param->sampling_w[1] << 12) |
+ (param->sampling_h[1] << 8) |
+ (param->sampling_w[2] << 4) |
+ (param->sampling_h[2]);
+
+ param->uv_brz_w = 0;
+ switch (param->src_color) {
+ case MTK_JPEG_COLOR_444:
+ param->uv_brz_w = 1;
+ param->dst_fourcc = V4L2_PIX_FMT_YUV422M;
+ break;
+ case MTK_JPEG_COLOR_422X2:
+ case MTK_JPEG_COLOR_422:
+ param->dst_fourcc = V4L2_PIX_FMT_YUV422M;
+ break;
+ case MTK_JPEG_COLOR_422V:
+ case MTK_JPEG_COLOR_422VX2:
+ param->uv_brz_w = 1;
+ param->dst_fourcc = V4L2_PIX_FMT_YUV420M;
+ break;
+ case MTK_JPEG_COLOR_420:
+ param->dst_fourcc = V4L2_PIX_FMT_YUV420M;
+ break;
+ case MTK_JPEG_COLOR_400:
+ param->dst_fourcc = V4L2_PIX_FMT_GREY;
+ break;
+ default:
+ param->dst_fourcc = 0;
+ return -1;
+ }
+
+ return 0;
+}
+
+static void mtk_jpeg_calc_mcu(struct mtk_jpeg_dec_param *param)
+{
+ u32 factor_w, factor_h;
+ u32 i, comp, blk;
+
+ factor_w = 2 + param->sampling_w[0];
+ factor_h = 2 + param->sampling_h[0];
+ param->mcu_w = (param->pic_w + (1 << factor_w) - 1) >> factor_w;
+ param->mcu_h = (param->pic_h + (1 << factor_h) - 1) >> factor_h;
+ param->total_mcu = param->mcu_w * param->mcu_h;
+ param->unit_num = ((param->pic_w + 7) >> 3) * ((param->pic_h + 7) >> 3);
+ param->blk_num = 0;
+ for (i = 0; i < MTK_JPEG_COMP_MAX; i++) {
+ param->blk_comp[i] = 0;
+ if (i >= param->comp_num)
+ continue;
+ param->blk_comp[i] = param->sampling_w[i] *
+ param->sampling_h[i];
+ param->blk_num += param->blk_comp[i];
+ }
+
+ param->membership = 0;
+ for (i = 0, blk = 0, comp = 0; i < MTK_JPEG_BLOCK_MAX; i++) {
+ if (i < param->blk_num && comp < param->comp_num) {
+ u32 tmp;
+
+ tmp = (0x04 + (comp & 0x3));
+ param->membership |= tmp << (i * 3);
+ if (++blk == param->blk_comp[comp]) {
+ comp++;
+ blk = 0;
+ }
+ } else {
+ param->membership |= 7 << (i * 3);
+ }
+ }
+}
+
+static void mtk_jpeg_calc_dma_group(struct mtk_jpeg_dec_param *param)
+{
+ u32 factor_mcu = 3;
+
+ if (param->src_color == MTK_JPEG_COLOR_444 &&
+ param->dst_fourcc == V4L2_PIX_FMT_YUV422M)
+ factor_mcu = 4;
+ else if (param->src_color == MTK_JPEG_COLOR_422V &&
+ param->dst_fourcc == V4L2_PIX_FMT_YUV420M)
+ factor_mcu = 4;
+ else if (param->src_color == MTK_JPEG_COLOR_422X2 &&
+ param->dst_fourcc == V4L2_PIX_FMT_YUV422M)
+ factor_mcu = 2;
+ else if (param->src_color == MTK_JPEG_COLOR_400 ||
+ (param->src_color & 0x0FFFF) == 0)
+ factor_mcu = 4;
+
+ param->dma_mcu = 1 << factor_mcu;
+ param->dma_group = param->mcu_w / param->dma_mcu;
+ param->dma_last_mcu = param->mcu_w % param->dma_mcu;
+ if (param->dma_last_mcu)
+ param->dma_group++;
+ else
+ param->dma_last_mcu = param->dma_mcu;
+}
+
+static int mtk_jpeg_calc_dst_size(struct mtk_jpeg_dec_param *param)
+{
+ u32 i, padding_w;
+ u32 ds_row_h[3];
+ u32 brz_w[3];
+
+ brz_w[0] = 0;
+ brz_w[1] = param->uv_brz_w;
+ brz_w[2] = brz_w[1];
+
+ for (i = 0; i < param->comp_num; i++) {
+ if (brz_w[i] > 3)
+ return -1;
+
+ padding_w = param->mcu_w * MTK_JPEG_DCTSIZE *
+ param->sampling_w[i];
+ /* output format is 420/422 */
+ param->comp_w[i] = padding_w >> brz_w[i];
+ param->comp_w[i] = mtk_jpeg_align(param->comp_w[i],
+ MTK_JPEG_DCTSIZE);
+ param->img_stride[i] = i ? mtk_jpeg_align(param->comp_w[i], 16)
+ : mtk_jpeg_align(param->comp_w[i], 32);
+ ds_row_h[i] = (MTK_JPEG_DCTSIZE * param->sampling_h[i]);
+ }
+ param->dec_w = param->img_stride[0];
+ param->dec_h = ds_row_h[0] * param->mcu_h;
+
+ for (i = 0; i < MTK_JPEG_COMP_MAX; i++) {
+ /* They must be equal in frame mode. */
+ param->mem_stride[i] = param->img_stride[i];
+ param->comp_size[i] = param->mem_stride[i] * ds_row_h[i] *
+ param->mcu_h;
+ }
+
+ param->y_size = param->comp_size[0];
+ param->uv_size = param->comp_size[1];
+ param->dec_size = param->y_size + (param->uv_size << 1);
+
+ return 0;
+}
+
+int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param *param)
+{
+ if (mtk_jpeg_decide_format(param))
+ return -1;
+
+ mtk_jpeg_calc_mcu(param);
+ mtk_jpeg_calc_dma_group(param);
+ if (mtk_jpeg_calc_dst_size(param))
+ return -2;
+
+ return 0;
+}
+
+u32 mtk_jpeg_dec_get_int_status(void __iomem *base)
+{
+ u32 ret;
+
+ ret = readl(base + JPGDEC_REG_INTERRUPT_STATUS) & BIT_INQST_MASK_ALLIRQ;
+ if (ret)
+ writel(ret, base + JPGDEC_REG_INTERRUPT_STATUS);
+
+ return ret;
+}
+
+u32 mtk_jpeg_dec_enum_result(u32 irq_result)
+{
+ if (irq_result & BIT_INQST_MASK_EOF)
+ return MTK_JPEG_DEC_RESULT_EOF_DONE;
+ if (irq_result & BIT_INQST_MASK_PAUSE)
+ return MTK_JPEG_DEC_RESULT_PAUSE;
+ if (irq_result & BIT_INQST_MASK_UNDERFLOW)
+ return MTK_JPEG_DEC_RESULT_UNDERFLOW;
+ if (irq_result & BIT_INQST_MASK_OVERFLOW)
+ return MTK_JPEG_DEC_RESULT_OVERFLOW;
+ if (irq_result & BIT_INQST_MASK_ERROR_BS)
+ return MTK_JPEG_DEC_RESULT_ERROR_BS;
+
+ return MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN;
+}
+
+void mtk_jpeg_dec_start(void __iomem *base)
+{
+ writel(0, base + JPGDEC_REG_TRIG);
+}
+
+static void mtk_jpeg_dec_soft_reset(void __iomem *base)
+{
+ writel(0x0000FFFF, base + JPGDEC_REG_INTERRUPT_STATUS);
+ writel(0x00, base + JPGDEC_REG_RESET);
+ writel(0x01, base + JPGDEC_REG_RESET);
+}
+
+static void mtk_jpeg_dec_hard_reset(void __iomem *base)
+{
+ writel(0x00, base + JPGDEC_REG_RESET);
+ writel(0x10, base + JPGDEC_REG_RESET);
+}
+
+void mtk_jpeg_dec_reset(void __iomem *base)
+{
+ mtk_jpeg_dec_soft_reset(base);
+ mtk_jpeg_dec_hard_reset(base);
+}
+
+static void mtk_jpeg_dec_set_brz_factor(void __iomem *base, u8 yscale_w,
+ u8 yscale_h, u8 uvscale_w, u8 uvscale_h)
+{
+ u32 val;
+
+ val = (uvscale_h << 12) | (uvscale_w << 8) |
+ (yscale_h << 4) | yscale_w;
+ writel(val, base + JPGDEC_REG_BRZ_FACTOR);
+}
+
+static void mtk_jpeg_dec_set_dst_bank0(void __iomem *base, u32 addr_y,
+ u32 addr_u, u32 addr_v)
+{
+ mtk_jpeg_verify_align(addr_y, 16, JPGDEC_REG_DEST_ADDR0_Y);
+ writel(addr_y, base + JPGDEC_REG_DEST_ADDR0_Y);
+ mtk_jpeg_verify_align(addr_u, 16, JPGDEC_REG_DEST_ADDR0_U);
+ writel(addr_u, base + JPGDEC_REG_DEST_ADDR0_U);
+ mtk_jpeg_verify_align(addr_v, 16, JPGDEC_REG_DEST_ADDR0_V);
+ writel(addr_v, base + JPGDEC_REG_DEST_ADDR0_V);
+}
+
+static void mtk_jpeg_dec_set_dst_bank1(void __iomem *base, u32 addr_y,
+ u32 addr_u, u32 addr_v)
+{
+ writel(addr_y, base + JPGDEC_REG_DEST_ADDR1_Y);
+ writel(addr_u, base + JPGDEC_REG_DEST_ADDR1_U);
+ writel(addr_v, base + JPGDEC_REG_DEST_ADDR1_V);
+}
+
+static void mtk_jpeg_dec_set_mem_stride(void __iomem *base, u32 stride_y,
+ u32 stride_uv)
+{
+ writel((stride_y & 0xFFFF), base + JPGDEC_REG_STRIDE_Y);
+ writel((stride_uv & 0xFFFF), base + JPGDEC_REG_STRIDE_UV);
+}
+
+static void mtk_jpeg_dec_set_img_stride(void __iomem *base, u32 stride_y,
+ u32 stride_uv)
+{
+ writel((stride_y & 0xFFFF), base + JPGDEC_REG_IMG_STRIDE_Y);
+ writel((stride_uv & 0xFFFF), base + JPGDEC_REG_IMG_STRIDE_UV);
+}
+
+static void mtk_jpeg_dec_set_pause_mcu_idx(void __iomem *base, u32 idx)
+{
+ writel(idx & 0x0003FFFFFF, base + JPGDEC_REG_PAUSE_MCU_NUM);
+}
+
+static void mtk_jpeg_dec_set_dec_mode(void __iomem *base, u32 mode)
+{
+ writel(mode & 0x03, base + JPGDEC_REG_OPERATION_MODE);
+}
+
+static void mtk_jpeg_dec_set_bs_write_ptr(void __iomem *base, u32 ptr)
+{
+ mtk_jpeg_verify_align(ptr, 16, JPGDEC_REG_FILE_BRP);
+ writel(ptr, base + JPGDEC_REG_FILE_BRP);
+}
+
+static void mtk_jpeg_dec_set_bs_info(void __iomem *base, u32 addr, u32 size)
+{
+ mtk_jpeg_verify_align(addr, 16, JPGDEC_REG_FILE_ADDR);
+ mtk_jpeg_verify_align(size, 128, JPGDEC_REG_FILE_TOTAL_SIZE);
+ writel(addr, base + JPGDEC_REG_FILE_ADDR);
+ writel(size, base + JPGDEC_REG_FILE_TOTAL_SIZE);
+}
+
+static void mtk_jpeg_dec_set_comp_id(void __iomem *base, u32 id_y, u32 id_u,
+ u32 id_v)
+{
+ u32 val;
+
+ val = ((id_y & 0x00FF) << 24) | ((id_u & 0x00FF) << 16) |
+ ((id_v & 0x00FF) << 8);
+ writel(val, base + JPGDEC_REG_COMP_ID);
+}
+
+static void mtk_jpeg_dec_set_total_mcu(void __iomem *base, u32 num)
+{
+ writel(num - 1, base + JPGDEC_REG_TOTAL_MCU_NUM);
+}
+
+static void mtk_jpeg_dec_set_comp0_du(void __iomem *base, u32 num)
+{
+ writel(num - 1, base + JPGDEC_REG_COMP0_DATA_UNIT_NUM);
+}
+
+static void mtk_jpeg_dec_set_du_membership(void __iomem *base, u32 member,
+ u32 gmc, u32 isgray)
+{
+ if (isgray)
+ member = 0x3FFFFFFC;
+ member |= (isgray << 31) | (gmc << 30);
+ writel(member, base + JPGDEC_REG_DU_CTRL);
+}
+
+static void mtk_jpeg_dec_set_q_table(void __iomem *base, u32 id0, u32 id1,
+ u32 id2)
+{
+ u32 val;
+
+ val = ((id0 & 0x0f) << 8) | ((id1 & 0x0f) << 4) | ((id2 & 0x0f) << 0);
+ writel(val, base + JPGDEC_REG_QT_ID);
+}
+
+static void mtk_jpeg_dec_set_dma_group(void __iomem *base, u32 mcu_group,
+ u32 group_num, u32 last_mcu)
+{
+ u32 val;
+
+ val = (((mcu_group - 1) & 0x00FF) << 16) |
+ (((group_num - 1) & 0x007F) << 8) |
+ ((last_mcu - 1) & 0x00FF);
+ writel(val, base + JPGDEC_REG_WDMA_CTRL);
+}
+
+static void mtk_jpeg_dec_set_sampling_factor(void __iomem *base, u32 comp_num,
+ u32 y_w, u32 y_h, u32 u_w,
+ u32 u_h, u32 v_w, u32 v_h)
+{
+ u32 val;
+ u32 y_wh = (MTK_JPEG_DUNUM_MASK(y_w) << 2) | MTK_JPEG_DUNUM_MASK(y_h);
+ u32 u_wh = (MTK_JPEG_DUNUM_MASK(u_w) << 2) | MTK_JPEG_DUNUM_MASK(u_h);
+ u32 v_wh = (MTK_JPEG_DUNUM_MASK(v_w) << 2) | MTK_JPEG_DUNUM_MASK(v_h);
+
+ if (comp_num == 1)
+ val = 0;
+ else
+ val = (y_wh << 8) | (u_wh << 4) | v_wh;
+ writel(val, base + JPGDEC_REG_DU_NUM);
+}
+
+void mtk_jpeg_dec_set_config(void __iomem *base,
+ struct mtk_jpeg_dec_param *config,
+ struct mtk_jpeg_bs *bs,
+ struct mtk_jpeg_fb *fb)
+{
+ mtk_jpeg_dec_set_brz_factor(base, 0, 0, config->uv_brz_w, 0);
+ mtk_jpeg_dec_set_dec_mode(base, 0);
+ mtk_jpeg_dec_set_comp0_du(base, config->unit_num);
+ mtk_jpeg_dec_set_total_mcu(base, config->total_mcu);
+ mtk_jpeg_dec_set_bs_info(base, bs->str_addr, bs->size);
+ mtk_jpeg_dec_set_bs_write_ptr(base, bs->end_addr);
+ mtk_jpeg_dec_set_du_membership(base, config->membership, 1,
+ (config->comp_num == 1) ? 1 : 0);
+ mtk_jpeg_dec_set_comp_id(base, config->comp_id[0], config->comp_id[1],
+ config->comp_id[2]);
+ mtk_jpeg_dec_set_q_table(base, config->qtbl_num[0],
+ config->qtbl_num[1], config->qtbl_num[2]);
+ mtk_jpeg_dec_set_sampling_factor(base, config->comp_num,
+ config->sampling_w[0],
+ config->sampling_h[0],
+ config->sampling_w[1],
+ config->sampling_h[1],
+ config->sampling_w[2],
+ config->sampling_h[2]);
+ mtk_jpeg_dec_set_mem_stride(base, config->mem_stride[0],
+ config->mem_stride[1]);
+ mtk_jpeg_dec_set_img_stride(base, config->img_stride[0],
+ config->img_stride[1]);
+ mtk_jpeg_dec_set_dst_bank0(base, fb->plane_addr[0],
+ fb->plane_addr[1], fb->plane_addr[2]);
+ mtk_jpeg_dec_set_dst_bank1(base, 0, 0, 0);
+ mtk_jpeg_dec_set_dma_group(base, config->dma_mcu, config->dma_group,
+ config->dma_last_mcu);
+ mtk_jpeg_dec_set_pause_mcu_idx(base, config->total_mcu);
+}
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h
new file mode 100644
index 0000000..37152a6
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
+ * Rick Chang <rick.chang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MTK_JPEG_HW_H
+#define _MTK_JPEG_HW_H
+
+#include <media/videobuf2-core.h>
+
+#include "mtk_jpeg_core.h"
+#include "mtk_jpeg_reg.h"
+
+enum {
+ MTK_JPEG_DEC_RESULT_EOF_DONE = 0,
+ MTK_JPEG_DEC_RESULT_PAUSE = 1,
+ MTK_JPEG_DEC_RESULT_UNDERFLOW = 2,
+ MTK_JPEG_DEC_RESULT_OVERFLOW = 3,
+ MTK_JPEG_DEC_RESULT_ERROR_BS = 4,
+ MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN = 6
+};
+
+struct mtk_jpeg_dec_param {
+ u32 pic_w;
+ u32 pic_h;
+ u32 dec_w;
+ u32 dec_h;
+ u32 src_color;
+ u32 dst_fourcc;
+ u32 mcu_w;
+ u32 mcu_h;
+ u32 total_mcu;
+ u32 unit_num;
+ u32 comp_num;
+ u32 comp_id[MTK_JPEG_COMP_MAX];
+ u32 sampling_w[MTK_JPEG_COMP_MAX];
+ u32 sampling_h[MTK_JPEG_COMP_MAX];
+ u32 qtbl_num[MTK_JPEG_COMP_MAX];
+ u32 blk_num;
+ u32 blk_comp[MTK_JPEG_COMP_MAX];
+ u32 membership;
+ u32 dma_mcu;
+ u32 dma_group;
+ u32 dma_last_mcu;
+ u32 img_stride[MTK_JPEG_COMP_MAX];
+ u32 mem_stride[MTK_JPEG_COMP_MAX];
+ u32 comp_w[MTK_JPEG_COMP_MAX];
+ u32 comp_size[MTK_JPEG_COMP_MAX];
+ u32 y_size;
+ u32 uv_size;
+ u32 dec_size;
+ u8 uv_brz_w;
+};
+
+static inline u32 mtk_jpeg_align(u32 val, u32 align)
+{
+ return (val + align - 1) & ~(align - 1);
+}
+
+struct mtk_jpeg_bs {
+ dma_addr_t str_addr;
+ dma_addr_t end_addr;
+ size_t size;
+};
+
+struct mtk_jpeg_fb {
+ dma_addr_t plane_addr[MTK_JPEG_COMP_MAX];
+ size_t size;
+};
+
+int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param *param);
+u32 mtk_jpeg_dec_get_int_status(void __iomem *dec_reg_base);
+u32 mtk_jpeg_dec_enum_result(u32 irq_result);
+void mtk_jpeg_dec_set_config(void __iomem *base,
+ struct mtk_jpeg_dec_param *config,
+ struct mtk_jpeg_bs *bs,
+ struct mtk_jpeg_fb *fb);
+void mtk_jpeg_dec_reset(void __iomem *dec_reg_base);
+void mtk_jpeg_dec_start(void __iomem *dec_reg_base);
+
+#endif /* _MTK_JPEG_HW_H */
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
new file mode 100644
index 0000000..3886854
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
+ * Rick Chang <rick.chang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/videodev2.h>
+
+#include "mtk_jpeg_parse.h"
+
+#define TEM 0x01
+#define SOF0 0xc0
+#define RST 0xd0
+#define SOI 0xd8
+#define EOI 0xd9
+
+struct mtk_jpeg_stream {
+ u8 *addr;
+ u32 size;
+ u32 curr;
+};
+
+static int read_byte(struct mtk_jpeg_stream *stream)
+{
+ if (stream->curr >= stream->size)
+ return -1;
+ return stream->addr[stream->curr++];
+}
+
+static int read_word_be(struct mtk_jpeg_stream *stream, u32 *word)
+{
+ u32 temp;
+ int byte;
+
+ byte = read_byte(stream);
+ if (byte == -1)
+ return -1;
+ temp = byte << 8;
+ byte = read_byte(stream);
+ if (byte == -1)
+ return -1;
+ *word = (u32)byte | temp;
+
+ return 0;
+}
+
+static void read_skip(struct mtk_jpeg_stream *stream, long len)
+{
+ if (len <= 0)
+ return;
+ while (len--)
+ read_byte(stream);
+}
+
+static bool mtk_jpeg_do_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
+ u32 src_size)
+{
+ bool notfound = true;
+ struct mtk_jpeg_stream stream;
+
+ stream.addr = src_addr_va;
+ stream.size = src_size;
+ stream.curr = 0;
+
+ while (notfound) {
+ int i, length, byte;
+ u32 word;
+
+ byte = read_byte(&stream);
+ if (byte == -1)
+ return false;
+ if (byte != 0xff)
+ continue;
+ do
+ byte = read_byte(&stream);
+ while (byte == 0xff);
+ if (byte == -1)
+ return false;
+ if (byte == 0)
+ continue;
+
+ length = 0;
+ switch (byte) {
+ case SOF0:
+ /* length */
+ if (read_word_be(&stream, &word))
+ break;
+
+ /* precision */
+ if (read_byte(&stream) == -1)
+ break;
+
+ if (read_word_be(&stream, &word))
+ break;
+ param->pic_h = word;
+
+ if (read_word_be(&stream, &word))
+ break;
+ param->pic_w = word;
+
+ param->comp_num = read_byte(&stream);
+ if (param->comp_num != 1 && param->comp_num != 3)
+ break;
+
+ for (i = 0; i < param->comp_num; i++) {
+ param->comp_id[i] = read_byte(&stream);
+ if (param->comp_id[i] == -1)
+ break;
+
+ /* sampling */
+ byte = read_byte(&stream);
+ if (byte == -1)
+ break;
+ param->sampling_w[i] = (byte >> 4) & 0x0F;
+ param->sampling_h[i] = byte & 0x0F;
+
+ param->qtbl_num[i] = read_byte(&stream);
+ if (param->qtbl_num[i] == -1)
+ break;
+ }
+
+ notfound = !(i == param->comp_num);
+ break;
+ case RST ... RST + 7:
+ case SOI:
+ case EOI:
+ case TEM:
+ break;
+ default:
+ if (read_word_be(&stream, &word))
+ break;
+ length = (long)word - 2;
+ read_skip(&stream, length);
+ break;
+ }
+ }
+
+ return !notfound;
+}
+
+bool mtk_jpeg_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
+ u32 src_size)
+{
+ if (!mtk_jpeg_do_parse(param, src_addr_va, src_size))
+ return false;
+ if (mtk_jpeg_dec_fill_param(param))
+ return false;
+
+ return true;
+}
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h
new file mode 100644
index 0000000..5d92340
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
+ * Rick Chang <rick.chang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MTK_JPEG_PARSE_H
+#define _MTK_JPEG_PARSE_H
+
+#include "mtk_jpeg_hw.h"
+
+bool mtk_jpeg_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
+ u32 src_size);
+
+#endif /* _MTK_JPEG_PARSE_H */
+
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h
new file mode 100644
index 0000000..fc490d6
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
+ * Rick Chang <rick.chang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MTK_JPEG_REG_H
+#define _MTK_JPEG_REG_H
+
+#define MTK_JPEG_COMP_MAX 3
+#define MTK_JPEG_BLOCK_MAX 10
+#define MTK_JPEG_DCTSIZE 8
+
+#define BIT_INQST_MASK_ERROR_BS 0x20
+#define BIT_INQST_MASK_PAUSE 0x10
+#define BIT_INQST_MASK_OVERFLOW 0x04
+#define BIT_INQST_MASK_UNDERFLOW 0x02
+#define BIT_INQST_MASK_EOF 0x01
+#define BIT_INQST_MASK_ALLIRQ 0x37
+
+#define JPGDEC_REG_RESET 0x0090
+#define JPGDEC_REG_BRZ_FACTOR 0x00F8
+#define JPGDEC_REG_DU_NUM 0x00FC
+#define JPGDEC_REG_DEST_ADDR0_Y 0x0140
+#define JPGDEC_REG_DEST_ADDR0_U 0x0144
+#define JPGDEC_REG_DEST_ADDR0_V 0x0148
+#define JPGDEC_REG_DEST_ADDR1_Y 0x014C
+#define JPGDEC_REG_DEST_ADDR1_U 0x0150
+#define JPGDEC_REG_DEST_ADDR1_V 0x0154
+#define JPGDEC_REG_STRIDE_Y 0x0158
+#define JPGDEC_REG_STRIDE_UV 0x015C
+#define JPGDEC_REG_IMG_STRIDE_Y 0x0160
+#define JPGDEC_REG_IMG_STRIDE_UV 0x0164
+#define JPGDEC_REG_WDMA_CTRL 0x016C
+#define JPGDEC_REG_PAUSE_MCU_NUM 0x0170
+#define JPGDEC_REG_OPERATION_MODE 0x017C
+#define JPGDEC_REG_FILE_ADDR 0x0200
+#define JPGDEC_REG_COMP_ID 0x020C
+#define JPGDEC_REG_TOTAL_MCU_NUM 0x0210
+#define JPGDEC_REG_COMP0_DATA_UNIT_NUM 0x0224
+#define JPGDEC_REG_DU_CTRL 0x023C
+#define JPGDEC_REG_TRIG 0x0240
+#define JPGDEC_REG_FILE_BRP 0x0248
+#define JPGDEC_REG_FILE_TOTAL_SIZE 0x024C
+#define JPGDEC_REG_QT_ID 0x0270
+#define JPGDEC_REG_INTERRUPT_STATUS 0x0274
+#define JPGDEC_REG_STATUS 0x0278
+
+#endif /* _MTK_JPEG_REG_H */
--
1.9.1
^ permalink raw reply related
* [PATCH v6 3/3] arm: dts: mt2701: Add node for Mediatek JPEG Decoder
From: Rick Chang @ 2016-11-17 3:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479353915-5043-1-git-send-email-rick.chang@mediatek.com>
Signed-off-by: Rick Chang <rick.chang@mediatek.com>
Signed-off-by: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
---
This patch depends on:
CCF "Add clock support for Mediatek MT2701"[1]
iommu and smi "Add the dtsi node of iommu and smi for mt2701"[2]
[1] http://lists.infradead.org/pipermail/linux-mediatek/2016-October/007271.html
[2] https://patchwork.kernel.org/patch/9164013/
---
arch/arm/boot/dts/mt2701.dtsi | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 8f13c70..4dd5048 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -298,6 +298,20 @@
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
};
+ jpegdec: jpegdec at 15004000 {
+ compatible = "mediatek,mt2701-jpgdec";
+ reg = <0 0x15004000 0 0x1000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&imgsys CLK_IMG_JPGDEC_SMI>,
+ <&imgsys CLK_IMG_JPGDEC>;
+ clock-names = "jpgdec-smi",
+ "jpgdec";
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
+ mediatek,larb = <&larb2>;
+ iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
+ <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
+ };
+
vdecsys: syscon at 16000000 {
compatible = "mediatek,mt2701-vdecsys", "syscon";
reg = <0 0x16000000 0 0x1000>;
--
1.9.1
^ permalink raw reply related
* [PATCH v1 2/4] mailbox: Add iProc mailbox controller driver
From: Jassi Brar @ 2016-11-17 3:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476817238-1226-3-git-send-email-jonathan.richardson@broadcom.com>
Hi Jonathan,
On Wed, Oct 19, 2016 at 12:30 AM, Jonathan Richardson
<jonathan.richardson@broadcom.com> wrote:
> The Broadcom iProc mailbox controller handles all communication with a
> Cortex-M0 MCU processor that provides support for power, clock, and
> reset management.
>
> Tested-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> Reviewed-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> Reviewed-by: Vikram Prakash <vikram.prakash@broadcom.com>
> Reviewed-by: Shreesha Rajashekar <shreesha.rajashekar@broadcom.com>
> Reviewed-by: Ray Jui <ray.jui@broadcom.com>
> Reviewed-by: Scott Branden <scott.branden@broadcom.com>
> Signed-off-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> ---
> drivers/mailbox/Kconfig | 10 +
> drivers/mailbox/Makefile | 2 +
> drivers/mailbox/bcm-iproc-mailbox.c | 422 ++++++++++++++++++++++++++++++++++++
> include/linux/bcm_iproc_mailbox.h | 32 +++
>
This should be include/linux/mailbox/bcm_iproc_mailbox.h
> +++ b/drivers/mailbox/bcm-iproc-mailbox.c
> @@ -0,0 +1,422 @@
> +/*
> + * Copyright (C) 2016 Broadcom.
> + *
> + * 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 version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/irq.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_device.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/notifier.h>
> +#include <linux/reboot.h>
> +#include <linux/mailbox_controller.h>
> +#include <linux/mailbox_client.h>
>
Need of mailbox_controller.h & client.h is a bad sign.
> +
> +static int iproc_mbox_send_data_m0_imp(struct iproc_mbox *mbox,
> + struct iproc_mbox_msg *msg, int max_retries, int poll_period_us)
> +{
> + unsigned long flags;
> + u32 val;
> + int err = 0;
> + int retries;
> +
> + spin_lock_irqsave(&mbox->lock, flags);
> +
> + dev_dbg(mbox->dev, "Send msg to M0: cmd=0x%x, param=0x%x, wait_ack=%d\n",
> + msg->cmd, msg->param, msg->wait_ack);
> +
> + writel(msg->cmd, mbox->base + IPROC_CRMU_MAILBOX0_OFFSET);
> + writel(msg->param, mbox->base + IPROC_CRMU_MAILBOX1_OFFSET);
> +
> + if (msg->wait_ack) {
> + err = msg->reply_code = -ETIMEDOUT;
> + for (retries = 0; retries < max_retries; retries++) {
> + val = readl(mbox->base + IPROC_CRMU_MAILBOX0_OFFSET);
> + if (val & M0_IPC_CMD_DONE_MASK) {
> + /*
> + * M0 replied - save reply code and
> + * clear error.
> + */
> + msg->reply_code = (val &
> + M0_IPC_CMD_REPLY_MASK) >>
> + M0_IPC_CMD_REPLY_SHIFT;
> + err = 0;
> + break;
> + }
> + udelay(poll_period_us);
> + }
> + }
> +
> + spin_unlock_irqrestore(&mbox->lock, flags);
> +
> + return err;
> +}
> +
OK, so this is the real message passing voodoo.
> +static void iproc_mbox_aon_gpio_forwarding_enable(struct iproc_mbox *mbox,
> + bool en)
> +{
> + struct iproc_mbox_msg msg;
> + const int max_retries = 5;
> + const int poll_period_us = 200;
> +
> + msg.cmd = M0_IPC_M0_CMD_AON_GPIO_FORWARDING_ENABLE;
> + msg.param = en ? 1 : 0;
> + msg.wait_ack = true;
> +
> + iproc_mbox_send_data_m0_imp(mbox, &msg, max_retries, poll_period_us);
> +}
> +
> +static void iproc_mbox_irq_unmask(struct irq_data *d)
> +{
> + struct iproc_mbox *iproc_mbox = irq_data_get_irq_chip_data(d);
> +
> + iproc_mbox_aon_gpio_forwarding_enable(iproc_mbox, true);
> +}
> +
> +static void iproc_mbox_irq_mask(struct irq_data *d)
> +{
> + /* Do nothing - Mask callback is not required, since upon GPIO event,
> + * M0 disables GPIO forwarding to A9. Hence, GPIO forwarding is already
> + * disabled when in mbox irq handler, and no other mbox events from M0
> + * to A9 are expected until GPIO forwarding is enabled following
> + * iproc_mbox_irq_unmask()
> + */
> +}
> +
> +static struct irq_chip iproc_mbox_irq_chip = {
> + .name = "bcm-iproc-mbox",
> + .irq_mask = iproc_mbox_irq_mask,
> + .irq_unmask = iproc_mbox_irq_unmask,
> +};
> +
.... these are simply using the mailbox controllers directly. So you
are actually clubbing a mailbox client (interrupt controller) with the
provider (mailbox) here.
I think you need move the IRQ controller part under drivers/irqchip/
that uses the mailbox api to manage its 'irq lines'.
Thanks.
^ permalink raw reply
* [PATCH v7 1/7] drm/hisilicon/hibmc: Add hisilicon hibmc drm master driver
From: Rongrong Zou @ 2016-11-17 4:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOw6vb+w3-qr+KFMYikVzVvS1n35sZPZFd8_8BRPCOgqVsGa8Q@mail.gmail.com>
Hi Sean,
Thanks for reviewing.
? 2016/11/16 23:42, Sean Paul ??:
> On Wed, Nov 16, 2016 at 8:43 AM, Rongrong Zou <zourongrong@gmail.com> wrote:
>> Add DRM master driver for Hisilicon Hibmc SoC which used for
>> Out-of-band management. Blow is the general hardware connection,
>> both the Hibmc and the host CPU are on the same mother board.
>>
>> +----------+ +----------+
>> | | PCIe | Hibmc |
>> |host CPU( |<----->| display |
>> |arm64,x86)| |subsystem |
>> +----------+ +----------+
>>
>> Signed-off-by: Rongrong Zou <zourongrong@gmail.com>
>> ---
>
> In the future, please keep track of the differences between patch
> versions. I noticed you have a short changelog in the cover letter,
> but it really helps to add one per-patch as well, it makes reviewing
> much simpler.
>
> Reviewed-by: Sean Paul <seanpaul@chromium.org>
Sorry for that, I will pay attention to it later, thanks.
Regards,
Rongrong.
>
>
>> drivers/gpu/drm/hisilicon/Kconfig | 1 +
>> drivers/gpu/drm/hisilicon/Makefile | 1 +
>> drivers/gpu/drm/hisilicon/hibmc/Kconfig | 9 +
>> drivers/gpu/drm/hisilicon/hibmc/Makefile | 4 +
>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 308 +++++++++++++++++++++++
>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 41 +++
>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h | 196 +++++++++++++++
>> 7 files changed, 560 insertions(+)
>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Kconfig
>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Makefile
>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h
>>
>> diff --git a/drivers/gpu/drm/hisilicon/Kconfig b/drivers/gpu/drm/hisilicon/Kconfig
>> index 558c61b..2fd2724 100644
>> --- a/drivers/gpu/drm/hisilicon/Kconfig
>> +++ b/drivers/gpu/drm/hisilicon/Kconfig
>> @@ -2,4 +2,5 @@
>> # hisilicon drm device configuration.
>> # Please keep this list sorted alphabetically
>>
>> +source "drivers/gpu/drm/hisilicon/hibmc/Kconfig"
>> source "drivers/gpu/drm/hisilicon/kirin/Kconfig"
>> diff --git a/drivers/gpu/drm/hisilicon/Makefile b/drivers/gpu/drm/hisilicon/Makefile
>> index e3f6d49..c8155bf 100644
>> --- a/drivers/gpu/drm/hisilicon/Makefile
>> +++ b/drivers/gpu/drm/hisilicon/Makefile
>> @@ -2,4 +2,5 @@
>> # Makefile for hisilicon drm drivers.
>> # Please keep this list sorted alphabetically
>>
>> +obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc/
>> obj-$(CONFIG_DRM_HISI_KIRIN) += kirin/
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
>> new file mode 100644
>> index 0000000..380622a
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
>> @@ -0,0 +1,9 @@
>> +config DRM_HISI_HIBMC
>> + tristate "DRM Support for Hisilicon Hibmc"
>> + depends on DRM && PCI
>> + select DRM_KMS_HELPER
>> + select DRM_TTM
>> +
>> + help
>> + Choose this option if you have a Hisilicon Hibmc soc chipset.
>> + If M is selected the module will be called hibmc-drm.
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
>> new file mode 100644
>> index 0000000..47962a0
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
>> @@ -0,0 +1,4 @@
>> +ccflags-y := -Iinclude/drm
>> +hibmc-drm-y := hibmc_drm_drv.o
>> +
>> +obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>> new file mode 100644
>> index 0000000..6d20580
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>> @@ -0,0 +1,308 @@
>> +/* Hisilicon Hibmc SoC drm driver
>> + *
>> + * Based on the bochs drm driver.
>> + *
>> + * Copyright (c) 2016 Huawei Limited.
>> + *
>> + * Author:
>> + * Rongrong Zou <zourongrong@huawei.com>
>> + * Rongrong Zou <zourongrong@gmail.com>
>> + * Jianhua Li <lijianhua@huawei.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + */
>> +
>> +#include <linux/console.h>
>> +#include <linux/module.h>
>> +
>> +#include "hibmc_drm_drv.h"
>> +#include "hibmc_drm_regs.h"
>> +
>> +static const struct file_operations hibmc_fops = {
>> + .owner = THIS_MODULE,
>> + .open = drm_open,
>> + .release = drm_release,
>> + .unlocked_ioctl = drm_ioctl,
>> + .compat_ioctl = drm_compat_ioctl,
>> + .poll = drm_poll,
>> + .read = drm_read,
>> + .llseek = no_llseek,
>> +};
>> +
>> +static int hibmc_enable_vblank(struct drm_device *dev, unsigned int pipe)
>> +{
>> + return 0;
>> +}
>> +
>> +static void hibmc_disable_vblank(struct drm_device *dev, unsigned int pipe)
>> +{
>> +}
>> +
>> +static struct drm_driver hibmc_driver = {
>> + .fops = &hibmc_fops,
>> + .name = "hibmc",
>> + .date = "20160828",
>> + .desc = "hibmc drm driver",
>> + .major = 1,
>> + .minor = 0,
>> + .get_vblank_counter = drm_vblank_no_hw_counter,
>> + .enable_vblank = hibmc_enable_vblank,
>> + .disable_vblank = hibmc_disable_vblank,
>> +};
>> +
>> +static int hibmc_pm_suspend(struct device *dev)
>> +{
>> + return 0;
>> +}
>> +
>> +static int hibmc_pm_resume(struct device *dev)
>> +{
>> + return 0;
>> +}
>> +
>> +static const struct dev_pm_ops hibmc_pm_ops = {
>> + SET_SYSTEM_SLEEP_PM_OPS(hibmc_pm_suspend,
>> + hibmc_pm_resume)
>> +};
>> +
>> +/*
>> + * It can operate in one of three modes: 0, 1 or Sleep.
>> + */
>> +void hibmc_set_power_mode(struct hibmc_drm_private *priv,
>> + unsigned int power_mode)
>> +{
>> + unsigned int control_value = 0;
>> + void __iomem *mmio = priv->mmio;
>> + unsigned int input = 1;
>> +
>> + if (power_mode > HIBMC_PW_MODE_CTL_MODE_SLEEP)
>> + return;
>> +
>> + if (power_mode == HIBMC_PW_MODE_CTL_MODE_SLEEP)
>> + input = 0;
>> +
>> + control_value = readl(mmio + HIBMC_POWER_MODE_CTRL);
>> + control_value &= ~(HIBMC_PW_MODE_CTL_MODE_MASK |
>> + HIBMC_PW_MODE_CTL_OSC_INPUT_MASK);
>> + control_value |= HIBMC_FIELD(HIBMC_PW_MODE_CTL_MODE, power_mode);
>> + control_value |= HIBMC_FIELD(HIBMC_PW_MODE_CTL_OSC_INPUT, input);
>> + writel(control_value, mmio + HIBMC_POWER_MODE_CTRL);
>> +}
>> +
>> +void hibmc_set_current_gate(struct hibmc_drm_private *priv, unsigned int gate)
>> +{
>> + unsigned int gate_reg;
>> + unsigned int mode;
>> + void __iomem *mmio = priv->mmio;
>> +
>> + /* Get current power mode. */
>> + mode = (readl(mmio + HIBMC_POWER_MODE_CTRL) &
>> + HIBMC_PW_MODE_CTL_MODE_MASK) >> HIBMC_PW_MODE_CTL_MODE_SHIFT;
>> +
>> + switch (mode) {
>> + case HIBMC_PW_MODE_CTL_MODE_MODE0:
>> + gate_reg = HIBMC_MODE0_GATE;
>> + break;
>> +
>> + case HIBMC_PW_MODE_CTL_MODE_MODE1:
>> + gate_reg = HIBMC_MODE1_GATE;
>> + break;
>> +
>> + default:
>> + gate_reg = HIBMC_MODE0_GATE;
>> + break;
>> + }
>> + writel(gate, mmio + gate_reg);
>> +}
>> +
>> +static void hibmc_hw_config(struct hibmc_drm_private *priv)
>> +{
>> + unsigned int reg;
>> +
>> + /* On hardware reset, power mode 0 is default. */
>> + hibmc_set_power_mode(priv, HIBMC_PW_MODE_CTL_MODE_MODE0);
>> +
>> + /* Enable display power gate & LOCALMEM power gate*/
>> + reg = readl(priv->mmio + HIBMC_CURRENT_GATE);
>> + reg &= ~HIBMC_CURR_GATE_DISPLAY_MASK;
>> + reg &= ~HIBMC_CURR_GATE_LOCALMEM_MASK;
>> + reg |= HIBMC_CURR_GATE_DISPLAY(1);
>> + reg |= HIBMC_CURR_GATE_LOCALMEM(1);
>> +
>> + hibmc_set_current_gate(priv, reg);
>> +
>> + /*
>> + * Reset the memory controller. If the memory controller
>> + * is not reset in chip,the system might hang when sw accesses
>> + * the memory.The memory should be resetted after
>> + * changing the MXCLK.
>> + */
>> + reg = readl(priv->mmio + HIBMC_MISC_CTRL);
>> + reg &= ~HIBMC_MSCCTL_LOCALMEM_RESET_MASK;
>> + reg |= HIBMC_MSCCTL_LOCALMEM_RESET(0);
>> + writel(reg, priv->mmio + HIBMC_MISC_CTRL);
>> +
>> + reg &= ~HIBMC_MSCCTL_LOCALMEM_RESET_MASK;
>> + reg |= HIBMC_MSCCTL_LOCALMEM_RESET(1);
>> +
>> + writel(reg, priv->mmio + HIBMC_MISC_CTRL);
>> +}
>> +
>> +static int hibmc_hw_map(struct hibmc_drm_private *priv)
>> +{
>> + struct drm_device *dev = priv->dev;
>> + struct pci_dev *pdev = dev->pdev;
>> + resource_size_t addr, size, ioaddr, iosize;
>> +
>> + ioaddr = pci_resource_start(pdev, 1);
>> + iosize = pci_resource_len(pdev, 1);
>> + priv->mmio = devm_ioremap_nocache(dev->dev, ioaddr, iosize);
>> + if (!priv->mmio) {
>> + DRM_ERROR("Cannot map mmio region\n");
>> + return -ENOMEM;
>> + }
>> +
>> + addr = pci_resource_start(pdev, 0);
>> + size = pci_resource_len(pdev, 0);
>> + priv->fb_map = devm_ioremap(dev->dev, addr, size);
>> + if (!priv->fb_map) {
>> + DRM_ERROR("Cannot map framebuffer\n");
>> + return -ENOMEM;
>> + }
>> + priv->fb_base = addr;
>> + priv->fb_size = size;
>> +
>> + return 0;
>> +}
>> +
>> +static int hibmc_hw_init(struct hibmc_drm_private *priv)
>> +{
>> + int ret;
>> +
>> + ret = hibmc_hw_map(priv);
>> + if (ret)
>> + return ret;
>> +
>> + hibmc_hw_config(priv);
>> +
>> + return 0;
>> +}
>> +
>> +static int hibmc_unload(struct drm_device *dev)
>> +{
>> + return 0;
>> +}
>> +
>> +static int hibmc_load(struct drm_device *dev)
>> +{
>> + struct hibmc_drm_private *priv;
>> + int ret;
>> +
>> + priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
>> + if (!priv) {
>> + DRM_ERROR("no memory to allocate for hibmc_drm_private\n");
>> + return -ENOMEM;
>> + }
>> + dev->dev_private = priv;
>> + priv->dev = dev;
>> +
>> + ret = hibmc_hw_init(priv);
>> + if (ret)
>> + goto err;
>> +
>> + return 0;
>> +
>> +err:
>> + hibmc_unload(dev);
>> + DRM_ERROR("failed to initialize drm driver: %d\n", ret);
>> + return ret;
>> +}
>> +
>> +static int hibmc_pci_probe(struct pci_dev *pdev,
>> + const struct pci_device_id *ent)
>> +{
>> + struct drm_device *dev;
>> + int ret;
>> +
>> + dev = drm_dev_alloc(&hibmc_driver, &pdev->dev);
>> + if (!dev) {
>> + DRM_ERROR("failed to allocate drm_device\n");
>> + return -ENOMEM;
>> + }
>> +
>> + dev->pdev = pdev;
>> + pci_set_drvdata(pdev, dev);
>> +
>> + ret = pci_enable_device(pdev);
>> + if (ret) {
>> + DRM_ERROR("failed to enable pci device: %d\n", ret);
>> + goto err_free;
>> + }
>> +
>> + ret = hibmc_load(dev);
>> + if (ret) {
>> + DRM_ERROR("failed to load hibmc: %d\n", ret);
>> + goto err_disable;
>> + }
>> +
>> + ret = drm_dev_register(dev, 0);
>> + if (ret) {
>> + DRM_ERROR("failed to register drv for userspace access: %d\n",
>> + ret);
>> + goto err_unload;
>> + }
>> + return 0;
>> +
>> +err_unload:
>> + hibmc_unload(dev);
>> +err_disable:
>> + pci_disable_device(pdev);
>> +err_free:
>> + drm_dev_unref(dev);
>> +
>> + return ret;
>> +}
>> +
>> +static void hibmc_pci_remove(struct pci_dev *pdev)
>> +{
>> + struct drm_device *dev = pci_get_drvdata(pdev);
>> +
>> + drm_dev_unregister(dev);
>> + hibmc_unload(dev);
>> + drm_dev_unref(dev);
>> +}
>> +
>> +static struct pci_device_id hibmc_pci_table[] = {
>> + {0x19e5, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
>> + {0,}
>> +};
>> +
>> +static struct pci_driver hibmc_pci_driver = {
>> + .name = "hibmc-drm",
>> + .id_table = hibmc_pci_table,
>> + .probe = hibmc_pci_probe,
>> + .remove = hibmc_pci_remove,
>> + .driver.pm = &hibmc_pm_ops,
>> +};
>> +
>> +static int __init hibmc_init(void)
>> +{
>> + return pci_register_driver(&hibmc_pci_driver);
>> +}
>> +
>> +static void __exit hibmc_exit(void)
>> +{
>> + return pci_unregister_driver(&hibmc_pci_driver);
>> +}
>> +
>> +module_init(hibmc_init);
>> +module_exit(hibmc_exit);
>> +
>> +MODULE_DEVICE_TABLE(pci, hibmc_pci_table);
>> +MODULE_AUTHOR("RongrongZou <zourongrong@huawei.com>");
>> +MODULE_DESCRIPTION("DRM Driver for Hisilicon Hibmc");
>> +MODULE_LICENSE("GPL v2");
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> new file mode 100644
>> index 0000000..840cd5a
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> @@ -0,0 +1,41 @@
>> +/* Hisilicon Hibmc SoC drm driver
>> + *
>> + * Based on the bochs drm driver.
>> + *
>> + * Copyright (c) 2016 Huawei Limited.
>> + *
>> + * Author:
>> + * Rongrong Zou <zourongrong@huawei.com>
>> + * Rongrong Zou <zourongrong@gmail.com>
>> + * Jianhua Li <lijianhua@huawei.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + */
>> +
>> +#ifndef HIBMC_DRM_DRV_H
>> +#define HIBMC_DRM_DRV_H
>> +
>> +#include <drm/drmP.h>
>> +
>> +struct hibmc_drm_private {
>> + /* hw */
>> + void __iomem *mmio;
>> + void __iomem *fb_map;
>> + unsigned long fb_base;
>> + unsigned long fb_size;
>> +
>> + /* drm */
>> + struct drm_device *dev;
>> +
>> +};
>> +
>> +void hibmc_set_power_mode(struct hibmc_drm_private *priv,
>> + unsigned int power_mode);
>> +void hibmc_set_current_gate(struct hibmc_drm_private *priv,
>> + unsigned int gate);
>> +
>> +#endif
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h
>> new file mode 100644
>> index 0000000..f7035bf
>> --- /dev/null
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h
>> @@ -0,0 +1,196 @@
>> +/* Hisilicon Hibmc SoC drm driver
>> + *
>> + * Based on the bochs drm driver.
>> + *
>> + * Copyright (c) 2016 Huawei Limited.
>> + *
>> + * Author:
>> + * Rongrong Zou <zourongrong@huawei.com>
>> + * Rongrong Zou <zourongrong@gmail.com>
>> + * Jianhua Li <lijianhua@huawei.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + */
>> +
>> +#ifndef HIBMC_DRM_HW_H
>> +#define HIBMC_DRM_HW_H
>> +
>> +/* register definition */
>> +#define HIBMC_MISC_CTRL 0x4
>> +
>> +#define HIBMC_MSCCTL_LOCALMEM_RESET(x) ((x) << 6)
>> +#define HIBMC_MSCCTL_LOCALMEM_RESET_MASK 0x40
>> +
>> +#define HIBMC_CURRENT_GATE 0x000040
>> +#define HIBMC_CURR_GATE_DISPLAY(x) ((x) << 2)
>> +#define HIBMC_CURR_GATE_DISPLAY_MASK 0x4
>> +
>> +#define HIBMC_CURR_GATE_LOCALMEM(x) ((x) << 1)
>> +#define HIBMC_CURR_GATE_LOCALMEM_MASK 0x2
>> +
>> +#define HIBMC_MODE0_GATE 0x000044
>> +#define HIBMC_MODE1_GATE 0x000048
>> +#define HIBMC_POWER_MODE_CTRL 0x00004C
>> +
>> +#define HIBMC_PW_MODE_CTL_OSC_INPUT(x) ((x) << 3)
>> +#define HIBMC_PW_MODE_CTL_OSC_INPUT_MASK 0x8
>> +
>> +#define HIBMC_PW_MODE_CTL_MODE(x) ((x) << 0)
>> +#define HIBMC_PW_MODE_CTL_MODE_MASK 0x03
>> +#define HIBMC_PW_MODE_CTL_MODE_SHIFT 0
>> +
>> +#define HIBMC_PW_MODE_CTL_MODE_MODE0 0
>> +#define HIBMC_PW_MODE_CTL_MODE_MODE1 1
>> +#define HIBMC_PW_MODE_CTL_MODE_SLEEP 2
>> +
>> +#define HIBMC_PANEL_PLL_CTRL 0x00005C
>> +#define HIBMC_CRT_PLL_CTRL 0x000060
>> +
>> +#define HIBMC_PLL_CTRL_BYPASS(x) ((x) << 18)
>> +#define HIBMC_PLL_CTRL_BYPASS_MASK 0x40000
>> +
>> +#define HIBMC_PLL_CTRL_POWER(x) ((x) << 17)
>> +#define HIBMC_PLL_CTRL_POWER_MASK 0x20000
>> +
>> +#define HIBMC_PLL_CTRL_INPUT(x) ((x) << 16)
>> +#define HIBMC_PLL_CTRL_INPUT_MASK 0x10000
>> +
>> +#define HIBMC_PLL_CTRL_POD(x) ((x) << 14)
>> +#define HIBMC_PLL_CTRL_POD_MASK 0xC000
>> +
>> +#define HIBMC_PLL_CTRL_OD(x) ((x) << 12)
>> +#define HIBMC_PLL_CTRL_OD_MASK 0x3000
>> +
>> +#define HIBMC_PLL_CTRL_N(x) ((x) << 8)
>> +#define HIBMC_PLL_CTRL_N_MASK 0xF00
>> +
>> +#define HIBMC_PLL_CTRL_M(x) ((x) << 0)
>> +#define HIBMC_PLL_CTRL_M_MASK 0xFF
>> +
>> +#define HIBMC_CRT_DISP_CTL 0x80200
>> +
>> +#define HIBMC_CRT_DISP_CTL_CRTSELECT(x) ((x) << 25)
>> +#define HIBMC_CRT_DISP_CTL_CRTSELECT_MASK 0x2000000
>> +
>> +#define HIBMC_CRTSELECT_CRT 1
>> +
>> +#define HIBMC_CRT_DISP_CTL_CLOCK_PHASE(x) ((x) << 14)
>> +#define HIBMC_CRT_DISP_CTL_CLOCK_PHASE_MASK 0x4000
>> +
>> +#define HIBMC_CRT_DISP_CTL_VSYNC_PHASE(x) ((x) << 13)
>> +#define HIBMC_CRT_DISP_CTL_VSYNC_PHASE_MASK 0x2000
>> +
>> +#define HIBMC_CRT_DISP_CTL_HSYNC_PHASE(x) ((x) << 12)
>> +#define HIBMC_CRT_DISP_CTL_HSYNC_PHASE_MASK 0x1000
>> +
>> +#define HIBMC_CRT_DISP_CTL_TIMING(x) ((x) << 8)
>> +#define HIBMC_CRT_DISP_CTL_TIMING_MASK 0x100
>> +
>> +#define HIBMC_CRT_DISP_CTL_PLANE(x) ((x) << 2)
>> +#define HIBMC_CRT_DISP_CTL_PLANE_MASK 4
>> +
>> +#define HIBMC_CRT_DISP_CTL_FORMAT(x) ((x) << 0)
>> +#define HIBMC_CRT_DISP_CTL_FORMAT_MASK 0x03
>> +
>> +#define HIBMC_CRT_FB_ADDRESS 0x080204
>> +
>> +#define HIBMC_CRT_FB_WIDTH 0x080208
>> +#define HIBMC_CRT_FB_WIDTH_WIDTH(x) ((x) << 16)
>> +#define HIBMC_CRT_FB_WIDTH_WIDTH_MASK 0x3FFF0000
>> +#define HIBMC_CRT_FB_WIDTH_OFFS(x) ((x) << 0)
>> +#define HIBMC_CRT_FB_WIDTH_OFFS_MASK 0x3FFF
>> +
>> +#define HIBMC_CRT_HORZ_TOTAL 0x08020C
>> +#define HIBMC_CRT_HORZ_TOTAL_TOTAL(x) ((x) << 16)
>> +#define HIBMC_CRT_HORZ_TOTAL_TOTAL_MASK 0xFFF0000
>> +
>> +#define HIBMC_CRT_HORZ_TOTAL_DISP_END(x) ((x) << 0)
>> +#define HIBMC_CRT_HORZ_TOTAL_DISP_END_MASK 0xFFF
>> +
>> +#define HIBMC_CRT_HORZ_SYNC 0x080210
>> +#define HIBMC_CRT_HORZ_SYNC_WIDTH(x) ((x) << 16)
>> +#define HIBMC_CRT_HORZ_SYNC_WIDTH_MASK 0xFF0000
>> +
>> +#define HIBMC_CRT_HORZ_SYNC_START(x) ((x) << 0)
>> +#define HIBMC_CRT_HORZ_SYNC_START_MASK 0xFFF
>> +
>> +#define HIBMC_CRT_VERT_TOTAL 0x080214
>> +#define HIBMC_CRT_VERT_TOTAL_TOTAL(x) ((x) << 16)
>> +#define HIBMC_CRT_VERT_TOTAL_TOTAL_MASK 0x7FFF0000
>> +
>> +#define HIBMC_CRT_VERT_TOTAL_DISP_END(x) ((x) << 0)
>> +#define HIBMC_CRT_VERT_TOTAL_DISP_END_MASK 0x7FF
>> +
>> +#define HIBMC_CRT_VERT_SYNC 0x080218
>> +#define HIBMC_CRT_VERT_SYNC_HEIGHT(x) ((x) << 16)
>> +#define HIBMC_CRT_VERT_SYNC_HEIGHT_MASK 0x3F0000
>> +
>> +#define HIBMC_CRT_VERT_SYNC_START(x) ((x) << 0)
>> +#define HIBMC_CRT_VERT_SYNC_START_MASK 0x7FF
>> +
>> +/* Auto Centering */
>> +#define HIBMC_CRT_AUTO_CENTERING_TL 0x080280
>> +#define HIBMC_CRT_AUTO_CENTERING_TL_TOP(x) ((x) << 16)
>> +#define HIBMC_CRT_AUTO_CENTERING_TL_TOP_MASK 0x7FF0000
>> +
>> +#define HIBMC_CRT_AUTO_CENTERING_TL_LEFT(x) ((x) << 0)
>> +#define HIBMC_CRT_AUTO_CENTERING_TL_LEFT_MASK 0x7FF
>> +
>> +#define HIBMC_CRT_AUTO_CENTERING_BR 0x080284
>> +#define HIBMC_CRT_AUTO_CENTERING_BR_BOTTOM(x) ((x) << 16)
>> +#define HIBMC_CRT_AUTO_CENTERING_BR_BOTTOM_MASK 0x7FF0000
>> +
>> +#define HIBMC_CRT_AUTO_CENTERING_BR_RIGHT(x) ((x) << 0)
>> +#define HIBMC_CRT_AUTO_CENTERING_BR_RIGHT_MASK 0x7FF
>> +
>> +/* register to control panel output */
>> +#define HIBMC_DISPLAY_CONTROL_HISILE 0x80288
>> +#define HIBMC_DISPLAY_CONTROL_FPVDDEN(x) ((x) << 0)
>> +#define HIBMC_DISPLAY_CONTROL_PANELDATE(x) ((x) << 1)
>> +#define HIBMC_DISPLAY_CONTROL_FPEN(x) ((x) << 2)
>> +#define HIBMC_DISPLAY_CONTROL_VBIASEN(x) ((x) << 3)
>> +
>> +#define HIBMC_RAW_INTERRUPT 0x80290
>> +#define HIBMC_RAW_INTERRUPT_VBLANK(x) ((x) << 2)
>> +#define HIBMC_RAW_INTERRUPT_VBLANK_MASK 0x4
>> +
>> +#define HIBMC_RAW_INTERRUPT_EN 0x80298
>> +#define HIBMC_RAW_INTERRUPT_EN_VBLANK(x) ((x) << 2)
>> +#define HIBMC_RAW_INTERRUPT_EN_VBLANK_MASK 0x4
>> +
>> +/* register and values for PLL control */
>> +#define CRT_PLL1_HS 0x802a8
>> +#define CRT_PLL1_HS_OUTER_BYPASS(x) ((x) << 30)
>> +#define CRT_PLL1_HS_INTER_BYPASS(x) ((x) << 29)
>> +#define CRT_PLL1_HS_POWERON(x) ((x) << 24)
>> +
>> +#define CRT_PLL1_HS_25MHZ 0x23d40f02
>> +#define CRT_PLL1_HS_40MHZ 0x23940801
>> +#define CRT_PLL1_HS_65MHZ 0x23940d01
>> +#define CRT_PLL1_HS_78MHZ 0x23540F82
>> +#define CRT_PLL1_HS_74MHZ 0x23941dc2
>> +#define CRT_PLL1_HS_80MHZ 0x23941001
>> +#define CRT_PLL1_HS_80MHZ_1152 0x23540fc2
>> +#define CRT_PLL1_HS_108MHZ 0x23b41b01
>> +#define CRT_PLL1_HS_162MHZ 0x23480681
>> +#define CRT_PLL1_HS_148MHZ 0x23541dc2
>> +#define CRT_PLL1_HS_193MHZ 0x234807c1
>> +
>> +#define CRT_PLL2_HS 0x802ac
>> +#define CRT_PLL2_HS_25MHZ 0x206B851E
>> +#define CRT_PLL2_HS_40MHZ 0x30000000
>> +#define CRT_PLL2_HS_65MHZ 0x40000000
>> +#define CRT_PLL2_HS_78MHZ 0x50E147AE
>> +#define CRT_PLL2_HS_74MHZ 0x602B6AE7
>> +#define CRT_PLL2_HS_80MHZ 0x70000000
>> +#define CRT_PLL2_HS_108MHZ 0x80000000
>> +#define CRT_PLL2_HS_162MHZ 0xA0000000
>> +#define CRT_PLL2_HS_148MHZ 0xB0CCCCCD
>> +#define CRT_PLL2_HS_193MHZ 0xC0872B02
>> +
>> +#define HIBMC_FIELD(field, value) (field(value) & field##_MASK)
>> +#endif
>> --
>> 1.9.1
>>
> _______________________________________________
> linuxarm mailing list
> linuxarm at huawei.com
> http://rnd-openeuler.huawei.com/mailman/listinfo/linuxarm
>
> .
>
^ permalink raw reply
* [PATCH v7 0/7] Add DRM driver for Hisilicon Hibmc
From: Rongrong Zou @ 2016-11-17 4:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOw6vbJHoELLTLpVjrfOZ8aEGzuDMFX5vWX8AxqNO35CT1iRxg@mail.gmail.com>
? 2016/11/17 0:02, Sean Paul ??:
> On Wed, Nov 16, 2016 at 11:01 AM, Sean Paul <seanpaul@chromium.org> wrote:
>> On Wed, Nov 16, 2016 at 8:43 AM, Rongrong Zou <zourongrong@gmail.com> wrote:
>>> This patch set adds a new drm driver for Hisilicon Hibmc. Hibmc is a
>>> BMC SoC with a display controller intergrated, usually it is used on
>>> server for Out-of-band management purpose. In this patch set, we just
>>> support basic function for Hibmc display subsystem. Hibmc display
>>> subsystem is connected to host CPU by PCIe as blow:
>>>
>>> +----------+ +----------+
>>> | | PCIe | Hibmc |
>>> |host CPU( |<----->| display |
>>> |arm64,x86)| |subsystem |
>>> +----------+ +----------+
>>>
>>> Hardware Detail for Hibmc display subsystem
>>> -----------
>>>
>>> The display subsystem of Hibmc is show as bellow:
>>> +----+ +----+ +----+ +--------+
>>> | | | | | | | |
>>> | FB |----->| DE |----->|VDAC|---->|external|
>>> | | | | | | | VGA |
>>> +----+ +----+ +----+ +--------+
>>>
>>> -DE(Display Engine) is the display controller.
>>> -VDAC(Video Digital-to-Analog converter) converts the RGB diaital data
>>> stream from DE to VGA analog signals.
>>>
>>
>> For the whole series/driver:
>>
>> Acked-by: Sean Paul <seanpaul@chromium.org>
>>
>>
>
> Also, please send those fixups for the other ttm drivers ;)
with pleasure :)
Regards,
Rongrong.
>
>>
>>> Change History
>>> ------------
>>> Changes in v7:
>>> -remove hibmc_drm_power.c/hibmc_drm_power.h, move the functions to
>>> hibmc_drm_drv.c.
>>> -remove hibmc_drm_de.h and move the struct defined in head file to
>>> hibmc_drm_de.c.
>>> -plane is initialized inside crtc, not in hibmc_kms_init().
>>> -connector is initialized inside encoder, not in hibmc_kms_init().
>>> -remove plane/crtc/encoder/connector from hibmc_drm_private struct.
>>> -call drm_atomic_helper_suspend/resume in hibmc_pm_suspend/resume.
>>> -remove these empty stubs because caller will do NULL check.
>>> hibmc_plane_atomic_disable
>>> hibmc_crtc_atomic_check
>>> hibmc_encoder_disable
>>> hibmc_encoder_enable
>>> hibmc_encoder_atomic_check
>>> -clean up in all error paths of creating driver-private framebuffer.
>>>
>>> Changes in v6:
>>> -remove the embedded framebuffer and use a pointer of hibmc_framebuffer
>>> instead.
>>> -remove the deprecated drm_framebuffer_unregister_private(),
>>> drm_framebuffer_unreference() will be called in hibmc_fbdev_destroy().
>>> -uninstall irq in hibmc_unload().
>>>
>>> Changes in v5:
>>> -rebase on v4.9-rc2.
>>> -replace drm_fb_helper_set_suspend with drm_fb_helper_set_suspend_unlocked.
>>> and remove redundant console_lock and console_unlock.
>>>
>>> Changes in v4:
>>> -remove unused include files, and include header file when it is needed.
>>> -remove unused FLAG in Kconfig: DRM_GEM_CMA_HELPER/DRM_KMS_CMA_HELPER.
>>> -remove drm_helper_disable_unused_functions, since we use DRIVER_ATOMIC.
>>>
>>> Changes in v3:
>>> -enable KMS, in v2, only fbdev is enabled.
>>> -management video memory with ttm.
>>> -add vblank interrupt.
>>> -remove drm_connector_register_all() and drm_connector_unregister_all().
>>> -I have a basic test with igt.
>>>
>>> Changes in v2:
>>> -Remove self-defined macros for bit operations.
>>> -Remove unused register.
>>> -Replace those deprecated functions with new version of them.
>>> -use drm_connector_register_all() to register connector after
>>> drm_dev_register().
>>>
>>> The patch v2 is at
>>> https://lists.freedesktop.org/archives/dri-devel/2016-May/108661.html
>>>
>>> Rongrong Zou (7):
>>> drm/hisilicon/hibmc: Add hisilicon hibmc drm master driver
>>> drm/hisilicon/hibmc: Add video memory management
>>> drm/hisilicon/hibmc: Add support for frame buffer
>>> drm/hisilicon/hibmc: Add support for display engine
>>> drm/hisilicon/hibmc: Add support for VDAC
>>> drm/hisilicon/hibmc: Add support for vblank interrupt
>>> MAINTAINERS: Update HISILICON DRM entries
>>>
>>> MAINTAINERS | 1 +
>>> drivers/gpu/drm/hisilicon/Kconfig | 1 +
>>> drivers/gpu/drm/hisilicon/Makefile | 1 +
>>> drivers/gpu/drm/hisilicon/hibmc/Kconfig | 9 +
>>> drivers/gpu/drm/hisilicon/hibmc/Makefile | 4 +
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 477 ++++++++++++++++++
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 456 ++++++++++++++++++
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 114 +++++
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c | 267 +++++++++++
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h | 196 ++++++++
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 147 ++++++
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 558 ++++++++++++++++++++++
>>> 12 files changed, 2231 insertions(+)
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Kconfig
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Makefile
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
>>> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
>>>
>>> --
>>> 1.9.1
>>>
> _______________________________________________
> linuxarm mailing list
> linuxarm at huawei.com
> http://rnd-openeuler.huawei.com/mailman/listinfo/linuxarm
>
> .
>
--
Regards, Rongrong
^ permalink raw reply
* [PATCH 01/16] ARM: scu: Provide support for parsing SCU device node to enable SCU
From: pankaj.dubey @ 2016-11-17 4:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161114145143.GM1041@n2100.armlinux.org.uk>
Hi Russell,
On Monday 14 November 2016 08:21 PM, Russell King - ARM Linux wrote:
> On Mon, Nov 14, 2016 at 03:37:44PM +0100, Arnd Bergmann wrote:
>> On Monday, November 14, 2016 1:50:18 PM CET Russell King - ARM Linux wrote:
>>> On Mon, Nov 14, 2016 at 01:03:09PM +0100, Arnd Bergmann wrote:
>>>> On Monday, November 14, 2016 2:10:16 PM CET pankaj.dubey wrote:
>>>>>>> + scu_base = of_iomap(np, 0);
>>>>>>> + of_node_put(np);
>>>>>>> + if (!scu_base) {
>>>>>>> + pr_err("%s failed to map scu_base via DT\n", __func__);
>>>>>>
>>>>>> For non-ca5, non-ca9 based SoCs, we'll see this error msg. We understand
>>>>>> what does it mean, but it may confuse normal users. In current version,
>>>>>> berlin doesn't complain like this for non-ca9 SoCs
>>>>>>
>>>>>
>>>>> OK, let me see other reviewer's comment on this. Then we will decide if
>>>>> this error message is required or can be omitted.
>>>>
>>>> We need to look at all callers here, to see if the function ever gets
>>>> called for a CPU that doesn't have an SCU. I'd say we should warn if
>>>> we know there is an SCU but we cannot map it, but never warn on
>>>> any of the CPU cores that don't support an SCU.
>>>
>>> Maybe there should be two helpers:
>>>
>>> of_scu_enable() which _only_ looks up the SCU address in DT and enables
>>> it if it finds it, otherwise returning failure.
>>>
>>> a9_scu_enable() which tries to use the A9 provided SCU address and
>>> enables it if it finds it, otherwise returning failure.
>>>
OK, In that case I can see need for following four helpers as:
1: of_scu_enable() which will __only__ lookup the SCU address in DT and
enables it if it finds, otherwise return -ENOMEM failure.
This helper APIs is required and sufficient for most of platforms such
as exynos, berlin, realview, socfpga, STi, ux500, vexpress, rockchip and
mvebu
2: a9_scu_enable(), which will __only__ use A9 provided SCU address and
enables it, if address mapped successfully, otherwise returning failure.
This helper APIs is required and sufficient for two ARM platforms as of
now tegra and hisi.
3: of_scu_get_base() which will lookup the SCU address in DT and if node
found maps address and returns ioremapped address to caller.
This helper APIs is required for three ARM plaforms rockchip, mvebu and
ux500, along with scu_enable() API to enable and find number_of_cores.
4: s9_scu_iomap_base() which will internally use s9_scu_get_base() and
do ioremap of scu address and returns ioremapped address to the caller
along with ownership (caller has responsibility to unmap it).
This helper APIs is required to simplify SCU enable and related code in
two ARM plaforms BCM ans ZX.
For remaining two ARM platforms (IMX and ZYNQ), none of these helpers
are useful for the time-being, as they need SCU mapping very early of
boot, where we can't use iomap APIs. So I will drop patches related to
these platforms in v2 version.
Please let me know if any concern in this approach.
>>> Then callers can decide which of these to call, and what error messages
>>> to print on their failures.
>>
>> Splitting the function in two is probably simpler overall, but
>> we may still have to look at all the callers: Any platform that
>> currently tries to map it on any CPU and doesn't warn about the
>> absence of the device node (or about scu_a9_has_base() == false)
>> should really continue not to warn about that.
>
> Did you miss the bit where none of of_scu_enable() or a9_scu_enable()
> should produce any warnings or errors to be printed. It's up to the
> caller to report the failure, otherwise doing this doesn't make sense:
>
> if (of_scu_enable() < 0 && a9_scu_enable() < 0)
> pr_err("Failed to map and enable the SCU\n");
>
> because if of_scu_enable() prints a warning/error, then it's patently
> misleading.
>
I will move out error message out of these helpers and let caller
(platform specific code) handle and print error if required.
Thanks,
Pankaj Dubey
^ permalink raw reply
* [PATCH 12/16] ARM: imx: use generic API for enabling SCU
From: pankaj.dubey @ 2016-11-17 4:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161114142631.GP3310@dragon>
Hi Shawn,
On Monday 14 November 2016 07:56 PM, Shawn Guo wrote:
> On Mon, Nov 14, 2016 at 10:32:07AM +0530, Pankaj Dubey wrote:
>> Now as we have of_scu_enable which takes care of mapping
>> scu base from DT, lets use it.
>>
>> At the same time this patch cleans up mach-imx platform files by
>> removing static mapping of SCU and dropping imx_scu_map_io function.
>
> I remember that the static mapping of SCU is necessary because SCU is
> being accessed at very early boot stage where dynamic mapping hasn't
> been set up.
>
>> CC: Shawn Guo <shawnguo@kernel.org>
>> CC: Sascha Hauer <kernel@pengutronix.de>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>> arch/arm/mach-imx/common.h | 5 -----
>> arch/arm/mach-imx/mach-imx6q.c | 8 +-------
>> arch/arm/mach-imx/platsmp.c | 32 +++++---------------------------
>> arch/arm/mach-imx/pm-imx6.c | 3 ++-
>> 4 files changed, 8 insertions(+), 40 deletions(-)
>
> I tested it and saw that the booting of imx6q is broken like below.
Thanks for testing and letting me know about this.
Currently only two platforms (IMX and ZYNQ) are using SCU address at
very early stage of boot, for configuring possible cpus via
set_cpu_possible().. rest platforms are either using DT method or they
handle this in smp_prepare_cpus.
Since I am not sure if all boards based on IMX has been moved to DT
based boot, if it has moved to completely DT based then we do not need
this set_cpu_possible in smp_init_cpus, it will be taken care via
"arm_dt_init_cpu_maps" and this will avoid need of early mapping of SCU
base as well.
If not then, currently I can't see any other way to handle this and in
that case I will drop-out IMX platform's patch of using generic SCU APIs
in v2 version of series.
Thanks,
Pankaj Dubey
^ permalink raw reply
* ILP32 for ARM64 - testing with lmbench
From: Maxim Kuvyrkov @ 2016-11-17 5:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cdf5cdf2-43af-6d7f-9e0c-72675fb83224@huawei.com>
Hi Bamvor,
I'm surprised that you see this much difference from ILP32 patches on SPEC CPU2006int at all. The SPEC CPU2006 benchmarks spend almost no time in the kernel syscalls. I can imagine memory, TLB, and cache handling in the kernel could affect CPU2006 benchmarks. Do ILP32 patches touch code in those areas?
Other than that, it would be interesting to check what the variance is between the 3 iterations of benchmark runs. Could you check what relative standard deviation is between the 3 iterations -- (STDEV(RUN1, RUN2, RUN3) / RUNselected)?
For reference, in my [non-ILP32] benchmarking I see 1.1% for 401.bzip2, 0.8% for 429.mcf, 0.2% for 456.hmmer, and 0.1% for 462.libquantum.
--
Maxim Kuvyrkov
www.linaro.org
> On Nov 17, 2016, at 7:28 AM, Zhangjian (Bamvor) <bamvor.zhangjian@huawei.com> wrote:
>
> Hi, all
>
> I test specint of aarch64 LP64 when aarch32 el0 disable/enabled respectively
> and compare with ILP32 unmerged kernel(4.8-rc6) in our arm64 board. I found
> that difference(ILP32 disabled/ILP32 unmerged) is bigger when aarch32 el0 is
> enabled, compare with aarch32 el0 disabled kernel. And bzip2, mcg, hmmer,
> libquantum are the top four differences[1]. Note that bigger is better in
> specint test.
>
> In order to make sure the above results, I retest these four testcases in
> reportable way(reference the command in the end). The result[2] show that
> libquantum decrease -2.09% after ILP32 enabled and aarch32 on. I think it is in
> significant.
>
> The result of lmbench is not stable in my board. I plan to dig it later.
>
> [1] The following test result is tested through --size=ref --iterations=3.
> 1.1 Test when aarch32_el0 is enabled.
> ILP32 disabled base line
> 400.perlbench 100.00% 100%
> 401.bzip2 99.35% 100%
> 403.gcc 100.26% 100%
> 429.mcf 102.75% 100%
> 445.gobmk 100.00% 100%
> 456.hmmer 95.66% 100%
> 458.sjeng 100.00% 100%
> 462.libquantum 100.00% 100%
> 471.omnetpp 100.59% 100%
> 473.astar 99.66% 100%
> 483.xalancbmk 99.10% 100%
>
> 1.2 Test when aarch32_el0 is disabled
> ILP32 disabled base line
> 400.perlbench 100.22% 100%
> 401.bzip2 100.95% 100%
> 403.gcc 100.20% 100%
> 429.mcf 100.76% 100%
> 445.gobmk 100.36% 100%
> 456.hmmer 97.94% 100%
> 458.sjeng 99.73% 100%
> 462.libquantum 98.72% 100%
> 471.omnetpp 100.86% 100%
> 473.astar 99.15% 100%
> 483.xalancbmk 100.08% 100%
>
> [2] The following test result is tested through: runspec --config=my.cfg --size=test,train,ref --noreportable --tune=base,peak --iterations=3 bzip2 mcf hmmer libquantum
> 2.1 Test when aarch32_el0 is enabled.
> ILP32_enabled base line
> 401.bzip2 100.82% 100%
> 429.mcf 100.18% 100%
> 456.hmmer 99.64% 100%
> 462.libquantum 97.91% 100%
>
> Regards
>
> Bamvor
>
> On 2016/10/28 20:46, Yury Norov wrote:
>> [Add Steve Ellcey, thanks for testing on ThunderX]
>>
>> Lmbench-3.0-a9 testing is performed on ThunderX machine to check that
>> ILP32 series does not add performance regressions for LP64. Test
>> summary is in the table below. Our measurements doesn't show
>> significant performance regression of LP64 if ILP32 code is merged,
>> both enabled or disabled.
>>
>> ILP32 enabled ILP32 disabled Standard Kernel
>> null syscall 0.1066 0.1121 0.1121
>> 95.09% 100.00%
>>
>> stat 1.3947 1.3814 1.3864
>> 100.60% 99.64%
>>
>> fstat 0.4459 0.4344 0.4524
>> 98.56% 96.02%
>>
>> open/close 4.0606 4.0411 4.0453
>> 100.38% 99.90%
>>
>> read 0.4819 0.5014 0.5014
>> 96.11% 100.00%
>>
>> Tested with linux 4.8 because 4.9-rc1 is not fixed yet for ThunderX.
>> Other system details below.
>>
>> Yury.
>>
>> ubuntu at crb6:~$ uname -a
>> Linux crb6 4.8.0+ #3 SMP Thu Oct 27 11:01:32 PDT 2016 aarch64 aarch64 aarch64 GNU/Linux
>>
>> ubuntu at crb6:~$ cat /proc/meminfo
>> MemTotal: 132011948 kB
>> MemFree: 131442672 kB
>> MemAvailable: 130695764 kB
>> Buffers: 15696 kB
>> Cached: 88088 kB
>> SwapCached: 0 kB
>> Active: 82760 kB
>> Inactive: 41336 kB
>> Active(anon): 20880 kB
>> Inactive(anon): 8576 kB
>> Active(file): 61880 kB
>> Inactive(file): 32760 kB
>> Unevictable: 0 kB
>> Mlocked: 0 kB
>> SwapTotal: 128920572 kB
>> SwapFree: 128920572 kB
>> Dirty: 0 kB
>> Writeback: 0 kB
>> AnonPages: 20544 kB
>> Mapped: 19780 kB
>> Shmem: 9060 kB
>> Slab: 78804 kB
>> SReclaimable: 27372 kB
>> SUnreclaim: 51432 kB
>> KernelStack: 8336 kB
>> PageTables: 820 kB
>> NFS_Unstable: 0 kB
>> Bounce: 0 kB
>> WritebackTmp: 0 kB
>> CommitLimit: 194926544 kB
>> Committed_AS: 256324 kB
>> VmallocTotal: 135290290112 kB
>> VmallocUsed: 0 kB
>> VmallocChunk: 0 kB
>> AnonHugePages: 0 kB
>> ShmemHugePages: 0 kB
>> ShmemPmdMapped: 0 kB
>> CmaTotal: 0 kB
>> CmaFree: 0 kB
>> HugePages_Total: 0
>> HugePages_Free: 0
>> HugePages_Rsvd: 0
>> HugePages_Surp: 0
>> Hugepagesize: 2048 kB
>>
>> ubuntu at crb6:~$ cat /proc/cpuinfo
>> processor : 0
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 1
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 2
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 3
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 4
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 5
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 6
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 7
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 8
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 9
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 10
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 11
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 12
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 13
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 14
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 15
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 16
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 17
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 18
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 19
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 20
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 21
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 22
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 23
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 24
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 25
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 26
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 27
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 28
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 29
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 30
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 31
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 32
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 33
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 34
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 35
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 36
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 37
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 38
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 39
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 40
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 41
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 42
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 43
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 44
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 45
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 46
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>> processor : 47
>> BogoMIPS : 200.00
>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>> CPU implementer : 0x43
>> CPU architecture: 8
>> CPU variant : 0x1
>> CPU part : 0x0a1
>> CPU revision : 0
>>
>
^ permalink raw reply
* [PATCH 1/1] drivers: dma-contiguous: Ensure cma reserve region never cross the low/high mem boundary
From: Jason Liu @ 2016-11-17 5:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6bd1a1a9-2bc0-f5f4-0957-1826af15f4dd@redhat.com>
> -----Original Message-----
> From: Laura Abbott [mailto:labbott at redhat.com]
> Sent: Thursday, November 17, 2016 4:00 AM
> To: Jason Liu <jason.hui.liu@nxp.com>; linux-arm-kernel at lists.infradead.org
> Cc: gregkh at linuxfoundation.org; iamjoonsoo.kim at lge.com; linux-
> kernel at vger.kernel.org; m.szyprowski at samsung.com
> Subject: Re: [PATCH 1/1] drivers: dma-contiguous: Ensure cma reserve region
> never cross the low/high mem boundary
>
> On 11/16/2016 06:19 AM, Jason Liu wrote:
> > If the cma reserve region goes through the device-tree method, also
> > need ensure the cma reserved region not cross the low/high mem
> > boundary. This patch did the similar fix as commit:16195dd
> > ("mm: cma: Ensure that reservations never cross the low/high mem
> > boundary")
> >
> > Signed-off-by: Jason Liu <jason.hui.liu@nxp.com>
> > Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> > Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > ---
> > drivers/base/dma-contiguous.c | 27 +++++++++++++++++++++++++++
> > 1 file changed, 27 insertions(+)
> >
> > diff --git a/drivers/base/dma-contiguous.c
> > b/drivers/base/dma-contiguous.c index e167a1e1..2bc093c 100644
> > --- a/drivers/base/dma-contiguous.c
> > +++ b/drivers/base/dma-contiguous.c
> > @@ -244,6 +244,7 @@ static int __init rmem_cma_setup(struct
> > reserved_mem *rmem) {
> > phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1,
> pageblock_order);
> > phys_addr_t mask = align - 1;
> > + phys_addr_t highmem_start;
> > unsigned long node = rmem->fdt_node;
> > struct cma *cma;
> > int err;
> > @@ -256,6 +257,32 @@ static int __init rmem_cma_setup(struct
> reserved_mem *rmem)
> > pr_err("Reserved memory: incorrect alignment of CMA
> region\n");
> > return -EINVAL;
> > }
> > +#ifdef CONFIG_X86
> > + /*
> > + * high_memory isn't direct mapped memory so retrieving its physical
> > + * address isn't appropriate. But it would be useful to check the
> > + * physical address of the highmem boundary so it's justfiable to get
> > + * the physical address from it. On x86 there is a validation check for
> > + * this case, so the following workaround is needed to avoid it.
> > + */
> > + highmem_start = __pa_nodebug(high_memory); #else
> > + highmem_start = __pa(high_memory);
> > +#endif
>
> The inline #ifdef is not great style, we shouldn't be spreading it around.
This is the similar fix in the 16195dd ("mm: cma: Ensure that reservations never cross
the low/high mem boundary". Do you have a better idea for this?
>
> > +
> > + /*
> > + * All pages in the reserved area must come from the same zone.
> > + * If the reserved region crosses the low/high memory boundary,
> > + * try to fix it up and then fall back to allocate from the low mem
> > + */
> > + if (rmem->base < highmem_start &&
> > + (rmem->base + rmem->size) > highmem_start) {
> > + memblock_free(rmem->base, rmem->size);
> > + rmem->base = memblock_alloc_range(rmem->size, align, 0,
> > + highmem_start,
> MEMBLOCK_NONE);
> > + if (!rmem->base)
> > + return -ENOMEM;
> > + }
>
> Given the alloc happened in the of code, it seems bad form to be bringing the
> free and re-alloc here. Perhaps we should be doing the limiting and checking in
> the reserved mem code?
I original though to fix it into the drivers/of/of_reserved_mem.c, but hesitate to
do it due to this of_reserved_mem is common code to do the reservation, which
is something not related with CMA requirement.
Appreciated that anyone can provide comments to improve this solution. Without this,
the Linux kernel will not boot up when do the CMA reservation from the DTS method,
since the dma_alloc_coherent will fail when do the dma memory allocation.
>
> If there is no other solution, at the least this deserves a pr_warn so users know
> why a reason specified may not be getting requested.
Yes, it deserves a pr_warn here. I will add it.
Thanks Laura for the review.
Jason Liu
>
> >
> > err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma);
> > if (err) {
> >
>
>
> Thanks,
> Laura
^ permalink raw reply
* [PATCH v27 1/9] memblock: add memblock_cap_memory_range()
From: AKASHI Takahiro @ 2016-11-17 5:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161116163015.GM7928@arm.com>
Will,
On Wed, Nov 16, 2016 at 04:30:15PM +0000, Will Deacon wrote:
> Hi Akashi,
>
> On Mon, Nov 14, 2016 at 02:55:16PM +0900, AKASHI Takahiro wrote:
> > On Fri, Nov 11, 2016 at 11:19:04AM +0800, Dennis Chen wrote:
> > > On Fri, Nov 11, 2016 at 11:50:50AM +0900, AKASHI Takahiro wrote:
> > > > On Thu, Nov 10, 2016 at 05:27:20PM +0000, Will Deacon wrote:
> > > > > On Wed, Nov 02, 2016 at 01:51:53PM +0900, AKASHI Takahiro wrote:
> > > > > > +void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
> > > > > > +{
> > > > > > + int start_rgn, end_rgn;
> > > > > > + int i, ret;
> > > > > > +
> > > > > > + if (!size)
> > > > > > + return;
> > > > > > +
> > > > > > + ret = memblock_isolate_range(&memblock.memory, base, size,
> > > > > > + &start_rgn, &end_rgn);
> > > > > > + if (ret)
> > > > > > + return;
> > > > > > +
> > > > > > + /* remove all the MAP regions */
> > > > > > + for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
> > > > > > + if (!memblock_is_nomap(&memblock.memory.regions[i]))
> > > > > > + memblock_remove_region(&memblock.memory, i);
> > > > > > +
> > > > > > + for (i = start_rgn - 1; i >= 0; i--)
> > > > > > + if (!memblock_is_nomap(&memblock.memory.regions[i]))
> > > > > > + memblock_remove_region(&memblock.memory, i);
> > > > > > +
> > > > > > + /* truncate the reserved regions */
> > > > > > + memblock_remove_range(&memblock.reserved, 0, base);
> > > > > > + memblock_remove_range(&memblock.reserved,
> > > > > > + base + size, (phys_addr_t)ULLONG_MAX);
> > > > > > +}
> > > > >
> > > > > This duplicates a bunch of the logic in memblock_mem_limit_remove_map. Can
> > > > > you not implement that in terms of your new, more general, function? e.g.
> > > > > by passing base == 0, and size == limit?
> > > >
> > > > Obviously it's possible.
> > > > I actually talked to Dennis before about merging them,
> > > > but he was against my idea.
> > > >
> > > Oops! I thought we have reached agreement in the thread:http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/442817.html
> > > So feel free to do that as Will'll do
> >
> > OK, but I found that the two functions have a bit different semantics
> > in clipping memory range, in particular, when the range [base,base+size)
> > goes across several regions with a gap.
> > (This does not happen in my arm64 kdump, though.)
> > That is, 'limit' in memblock_mem_limit_remove_map() means total size of
> > available memory, while 'size' in memblock_cap_memory_range() indicates
> > the size of _continuous_ memory range.
>
> I thought limit was just a physical address, and then
No, it's not.
> memblock_mem_limit_remove_map operated on the end of the nearest memblock?
No, but "max_addr" returned by __find_max_addr() is a physical address
and the end address of memory of "limit" size in total.
> You could leave the __find_max_addr call in memblock_mem_limit_remove_map,
> given that I don't think you need/want it for memblock_cap_memory_range.
>
> > So I added an extra argument, exact, to a common function to specify
> > distinct behaviors. Confusing? Please see the patch below.
>
> Oh yikes, this certainly wasn't what I had in mind! My observation was
> just that memblock_mem_limit_remove_map(limit) does:
>
>
> 1. memblock_isolate_range(limit - limit+ULLONG_MAX)
> 2. memblock_remove_region(all non-nomap regions in the isolated region)
> 3. truncate reserved regions to limit
>
> and your memblock_cap_memory_range(base, size) does:
>
> 1. memblock_isolate_range(base - base+size)
> 2, memblock_remove_region(all non-nomap regions above and below the
> isolated region)
> 3. truncate reserved regions around the isolated region
>
> so, assuming we can invert the isolation in one of the cases, then they
> could share the same underlying implementation.
Please see my simplified patch below which would explain what I meant.
(Note that the size is calculated by 'max_addr - 0'.)
> I'm probably just missing something here, because the patch you've ended
> up with is far more involved than I anticipated...
I hope that it will meet almost your anticipation.
Thanks,
-Takahiro AKASHI
>
> Will
===8<===
diff --git a/mm/memblock.c b/mm/memblock.c
index 7608bc3..fea1688 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1514,11 +1514,37 @@ void __init memblock_enforce_memory_limit(phys_addr_t limit)
(phys_addr_t)ULLONG_MAX);
}
+void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
+{
+ int start_rgn, end_rgn;
+ int i, ret;
+
+ if (!size)
+ return;
+
+ ret = memblock_isolate_range(&memblock.memory, base, size,
+ &start_rgn, &end_rgn);
+ if (ret)
+ return;
+
+ /* remove all the MAP regions */
+ for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
+ if (!memblock_is_nomap(&memblock.memory.regions[i]))
+ memblock_remove_region(&memblock.memory, i);
+
+ for (i = start_rgn - 1; i >= 0; i--)
+ if (!memblock_is_nomap(&memblock.memory.regions[i]))
+ memblock_remove_region(&memblock.memory, i);
+
+ /* truncate the reserved regions */
+ memblock_remove_range(&memblock.reserved, 0, base);
+ memblock_remove_range(&memblock.reserved,
+ base + size, (phys_addr_t)ULLONG_MAX);
+}
+
void __init memblock_mem_limit_remove_map(phys_addr_t limit)
{
- struct memblock_type *type = &memblock.memory;
phys_addr_t max_addr;
- int i, ret, start_rgn, end_rgn;
if (!limit)
return;
@@ -1529,19 +1555,7 @@ void __init memblock_mem_limit_remove_map(phys_addr_t limit)
if (max_addr == (phys_addr_t)ULLONG_MAX)
return;
- ret = memblock_isolate_range(type, max_addr, (phys_addr_t)ULLONG_MAX,
- &start_rgn, &end_rgn);
- if (ret)
- return;
-
- /* remove all the MAP regions above the limit */
- for (i = end_rgn - 1; i >= start_rgn; i--) {
- if (!memblock_is_nomap(&type->regions[i]))
- memblock_remove_region(type, i);
- }
- /* truncate the reserved regions */
- memblock_remove_range(&memblock.reserved, max_addr,
- (phys_addr_t)ULLONG_MAX);
+ memblock_cap_memory_range(0, max_addr);
}
static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)
^ permalink raw reply related
* [PATCH v5] drm/mediatek: fixed the calc method of data rate per lane
From: CK Hu @ 2016-11-17 5:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479266454-31892-1-git-send-email-jitao.shi@mediatek.com>
Hi, Jitao:
On Wed, 2016-11-16 at 11:20 +0800, Jitao Shi wrote:
> Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e.
> Tlpx, Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP
> mode, those signals will cause h-time larger than normal and reduce FPS.
> So need to multiply a coefficient to offset the extra signal's effect.
> coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+
> Ths_trail+Ths_exit)/(htotal*bpp/lane_number)
>
> Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
It looks good to me.
But this patch conflict with [1] which is one patch of MT2701 series. I
want to apply MT2701 patches first, so please help to refine this patch
based on MT2701 patches.
[1] https://patchwork.kernel.org/patch/9422821/
Regards,
CK
> ---
> Change since v4:
> - tune the calc comment more clear.
> - define the phy timings as constants.
>
> Chnage since v3:
> - wrapp the commit msg.
> - fix alignment of some lines.
>
> Change since v2:
> - move phy timing back to dsi_phy_timconfig.
>
> Change since v1:
> - phy_timing2 and phy_timing3 refer clock cycle time.
> - define values of LPX HS_PRPR HS_ZERO HS_TRAIL TA_GO TA_SURE TA_GET DA_HS_EXIT.
> ---
>
^ permalink raw reply
* [RFC PATCH] mfd: dt: Add Aspeed LPC binding
From: Andrew Jeffery @ 2016-11-17 6:06 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
I'd like to start a discussion about how to handle the LPC register space in
the Aspeed SoC. There are a number of issues, largely concerned with the layout
of the registers but also with the fact that LPC register state is used by the
pinmux to determine some pin functionality.
So the register layout is problematic. Registers for what I think are coherent
pieces of functionality functionality are littered through the layout: Post
Code Control registers (PCCR) are interleaved with LPC Host Controller
registers (LHCR) which are interleaved with Host Interface Controller registers
(HICR) which are segmented by LPC Snoop registers. It seems appropriate that
the whole thing is represented as an MFD syscon, with the alternative being
writing several distinct drivers that map some number of resources to access
all of their registers.
The disadvantage of not representing the LPC space as a syscon is the LPC Host
Controller driver will need to provide accessor functions for the pinmux
driver. Pinmux also depends on bits in the Display Controller, and would need
similar accessors provided there. The idea of using syscon regmaps removes the
need to write these accessors. If the changes between the AST2400 and AST2500
are anything to go by, the pinmux complexity of the SoCs will only increase
which will likely lead to the spread of these accessor functions.
Yet another option would be to only expose the LPC Host Controller as a syscon
instead of the whole LPC register space. I feel this is a little distasteful
as the LHCRs are not in contiguous memory space; as mentioned above they are
separated (seemingly randomly) by a PCCR. We could specify the LPC Host
Controller as a syscon and provide multiple resources: The syscon
implementation consumes the first resource which is what we desire here for use
with pinmux, but the driver would be left to map any subsequent resources. That
feels odd to me, but I'm interested in arguments for it.
We could also map the LPC Host Controller syscon across the offending PCCR, but
then any driver developed for the Post Code Controller would have to take a
reference to the LPC Host Controller regmap. I feel like we might wind up with
a syscon phandle spaghetti across the LPC controller if we use that approach.
Finally, the LPC registers can be divided in two: one set for H8S/2168
compatible LPC functionality, and the rest for Aspeed-specific registers.
Division in two is required if we are going to throw a regmap over the LPC
space as the H8S/2168 registers are 1-byte wide, whilst the Aspeed LPC
registers are 4-bytes. As far as I can tell we can treat them as separate
functionality without any loss; if there is a cross-over in configuration we
can have each phandle the other in the devicetree.
The final complication is the iBT device sits in the Aspeed-specific part of
the LPC controller and has an upstream driver that isn't regmap-capable.
Describing the LPC controller as a syscon will require some changes there, but
I think we can make it work without too much trouble.
What is the recommended approach to managing such hardware?
Cheers,
Andrew
PS: I sent a devicetree binding document out for the LPC Host Controller as
part of a recent pinmux series[1]. As it stands the example in the document
doesn't cover the all the registers relevant to the LPC Host Controller, which
was a motivation for trying to sort the problem out properly.
[1] https://www.spinics.net/lists/arm-kernel/msg540084.html
.../devicetree/bindings/mfd/aspeed-lpc.txt | 28 ++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
new file mode 100644
index 000000000000..36c8a9e08dc6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt
@@ -0,0 +1,28 @@
+* Device tree bindings for the Aspeed LPC Controller
+
+The Aspeed LPC controller contains registers for a variety of functions. Not
+all registers for a function are contiguous, and some registers are referenced
+by functions outside the LPC controller.
+
+Note that this is separate from the H8S/2168 compatible register set occupying
+the start of the LPC controller address space.
+
+Some significant functions in the LPC controller:
+
+* LPC Host Controller
+* Host Interface Controller
+* iBT Controller
+* SuperIO Scratch registers
+
+Required properties:
+- compatible: "aspeed,ast2500-lpc", "syscon"
+- reg: contains offset/length value of the Aspeed-specific LPC
+ memory region.
+
+Example:
+
+lpc: lpc at 1e7890a0 {
+ compatible = "aspeed,ast2500-lpc", "syscon";
+ reg = <0x1e789080 0x1e0>;
+};
+
--
2.9.3
^ permalink raw reply related
* [PATCH fpga 4/9] fpga zynq: Check for errors after completing DMA
From: Moritz Fischer @ 2016-11-17 6:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478732303-13718-5-git-send-email-jgunthorpe@obsidianresearch.com>
Hi Jason,
couple of minor things inline below:
On Wed, Nov 9, 2016 at 2:58 PM, Jason Gunthorpe
<jgunthorpe@obsidianresearch.com> wrote:
> The completion did not check the interrupt status to see if any error
> bits were asserted, check error bits and dump some registers if things
> went wrong.
>
> A few fixes are needed to make this work, the IXR_ERROR_FLAGS_MASK was
> wrong, it included the done bits, which shows a bug in mask/unmask_irqs
> which were using the wrong bits, simplify all of this stuff.
>
> Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
> ---
> drivers/fpga/zynq-fpga.c | 55 +++++++++++++++++++++++++++---------------------
> 1 file changed, 31 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
> index 40cf0feaca7c..3ffc5fcc3072 100644
> --- a/drivers/fpga/zynq-fpga.c
> +++ b/drivers/fpga/zynq-fpga.c
> @@ -89,7 +89,7 @@
> #define IXR_D_P_DONE_MASK BIT(12)
> /* FPGA programmed */
> #define IXR_PCFG_DONE_MASK BIT(2)
> -#define IXR_ERROR_FLAGS_MASK 0x00F0F860
> +#define IXR_ERROR_FLAGS_MASK 0x00F0C860
True. Ouch.
> #define IXR_ALL_MASK 0xF8F7F87F
>
> /* Miscellaneous constant values */
> @@ -144,23 +144,10 @@ static inline u32 zynq_fpga_read(const struct zynq_fpga_priv *priv,
> readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \
> timeout_us)
>
> -static void zynq_fpga_mask_irqs(struct zynq_fpga_priv *priv)
> +static inline void zynq_fpga_set_irq_mask(struct zynq_fpga_priv *priv,
> + u32 enable)
> {
> - u32 intr_mask;
> -
> - intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET);
> - zynq_fpga_write(priv, INT_MASK_OFFSET,
> - intr_mask | IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK);
> -}
> -
> -static void zynq_fpga_unmask_irqs(struct zynq_fpga_priv *priv)
> -{
> - u32 intr_mask;
> -
> - intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET);
> - zynq_fpga_write(priv, INT_MASK_OFFSET,
> - intr_mask
> - & ~(IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK));
> + zynq_fpga_write(priv, INT_MASK_OFFSET, ~enable);
Not a fan of this ~enable here. Function name indicates you're doing
the opposite
(see below comment).
> }
>
> static irqreturn_t zynq_fpga_isr(int irq, void *data)
> @@ -168,7 +155,7 @@ static irqreturn_t zynq_fpga_isr(int irq, void *data)
> struct zynq_fpga_priv *priv = data;
>
> /* disable DMA and error IRQs */
> - zynq_fpga_mask_irqs(priv);
> + zynq_fpga_set_irq_mask(priv, 0);
>
> complete(&priv->dma_done);
>
> @@ -314,6 +301,7 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
> const char *buf, size_t count)
> {
> struct zynq_fpga_priv *priv;
> + const char *why;
> int err;
> char *kbuf;
> dma_addr_t dma_addr;
> @@ -337,7 +325,7 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
> reinit_completion(&priv->dma_done);
>
> /* enable DMA and error IRQs */
> - zynq_fpga_unmask_irqs(priv);
> + zynq_fpga_set_irq_mask(priv, IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK);
I find the naming here confusing. This sets ~(IXR_D_P_DONE_MASK |
IXR_ERROR_FLAGS_MASK)
as mask value, to enable the D_P_DONE and error IRQs yet the function
name indicates the opposite.
>
> /* the +1 in the src addr is used to hold off on DMA_DONE IRQ
> * until both AXI and PCAP are done ...
> @@ -352,16 +340,35 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
> intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
> zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
>
> + if (intr_status & IXR_ERROR_FLAGS_MASK) {
> + why = "DMA reported error";
> + err = -EIO;
> + goto out_report;
> + }
> +
> if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
> - dev_err(priv->dev, "Error configuring FPGA\n");
> - err = -EFAULT;
> + why = "DMA did not complete";
> + err = -EIO;
> + goto out_report;
> }
>
> + err = 0;
> + goto out_clk;
> +
> +out_report:
> + dev_err(priv->dev,
> + "%s: INT_STS:0x%x CTRL:0x%x LOCK:0x%x INT_MASK:0x%x STATUS:0x%x MCTRL:0x%x\n",
> + why,
> + intr_status,
> + zynq_fpga_read(priv, CTRL_OFFSET),
> + zynq_fpga_read(priv, LOCK_OFFSET),
> + zynq_fpga_read(priv, INT_MASK_OFFSET),
> + zynq_fpga_read(priv, STATUS_OFFSET),
> + zynq_fpga_read(priv, MCTRL_OFFSET));
> +out_clk:
> clk_disable(priv->clk);
> -
Personally found it more readable with newline.
> out_free:
> dma_free_coherent(priv->dev, count, kbuf, dma_addr);
> -
Same here.
> return err;
> }
>
> @@ -475,7 +482,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
> /* unlock the device */
> zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
>
> - zynq_fpga_write(priv, INT_MASK_OFFSET, 0xFFFFFFFF);
> + zynq_fpga_set_irq_mask(priv, 0);
> zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
> err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev),
> priv);
> --
> 2.1.4
>
Thanks,
Moritz
^ permalink raw reply
* [PATCH v10 01/11] remoteproc: st_slim_rproc: add a slimcore rproc driver
From: Bjorn Andersson @ 2016-11-17 6:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161114051854.GW3000@localhost>
On Sun 13 Nov 21:18 PST 2016, Vinod Koul wrote:
> On Mon, Nov 07, 2016 at 01:57:35PM +0000, Peter Griffin wrote:
> > >
> > > As you now make changes to the entire remoteproc Kconfig file, rather
> > > than simply add a Kconfig symbol we can't bring this in via Vinod's tree
> > > without providing Linus with a messy merge conflict.
> > >
> > > So the remoteproc parts now has to go through my tree.
> >
> > OK, I think the best approach is for Vinod to create an immutable
> > branch with the entire fdma series on, and then both of you merge that branch into
> > your respective trees.
>
> my topic/st_fdma is immutable branch. You cna merge it, if you need a signed
> tag, please do let me know
>
Hi Vinod,
It looks like you reverted the wrong Kconfig fix, the one I objected to
was the change in drivers/remoteproc, not the one in drivers/dma.
The ST_FMDA depends on functions exposed by REMOTEPROC and
ST_SLIM_REMOTEPROC, the latter in turn depends on REMOTEPROC, which you
guys made user selectable - and as such should not be selected - but I
think we should move forward and get everything merged and then we can
go back and figure out how this should be addressed (or left alone?).
I have merged "topic/st_fdma" into rproc-next, so that I can fix up the
now broken drivers/remoteproc/Kconfig.
We do however both need to revert the revert or there will be link
errors if you build the dma driver with remoteproc=n. If you do this I
can merge the topic once more and we'll keep the set of changes in sync.
Regards,
Bjorn
^ permalink raw reply
* [PATCH v7 0/7] Add DRM driver for Hisilicon Hibmc
From: Xinliang Liu @ 2016-11-17 7:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479303831-74134-1-git-send-email-zourongrong@gmail.com>
Hi Rongrong,
Thanks for your hard work.
For this whole series patches:
Reviewed-by: Xinliang Liu <xinliang.liu@linaro.org>
Thanks,
-xinliang
On 16 November 2016 at 21:43, Rongrong Zou <zourongrong@gmail.com> wrote:
> This patch set adds a new drm driver for Hisilicon Hibmc. Hibmc is a
> BMC SoC with a display controller intergrated, usually it is used on
> server for Out-of-band management purpose. In this patch set, we just
> support basic function for Hibmc display subsystem. Hibmc display
> subsystem is connected to host CPU by PCIe as blow:
>
> +----------+ +----------+
> | | PCIe | Hibmc |
> |host CPU( |<----->| display |
> |arm64,x86)| |subsystem |
> +----------+ +----------+
>
> Hardware Detail for Hibmc display subsystem
> -----------
>
> The display subsystem of Hibmc is show as bellow:
> +----+ +----+ +----+ +--------+
> | | | | | | | |
> | FB |----->| DE |----->|VDAC|---->|external|
> | | | | | | | VGA |
> +----+ +----+ +----+ +--------+
>
> -DE(Display Engine) is the display controller.
> -VDAC(Video Digital-to-Analog converter) converts the RGB diaital data
> stream from DE to VGA analog signals.
>
> Change History
> ------------
> Changes in v7:
> -remove hibmc_drm_power.c/hibmc_drm_power.h, move the functions to
> hibmc_drm_drv.c.
> -remove hibmc_drm_de.h and move the struct defined in head file to
> hibmc_drm_de.c.
> -plane is initialized inside crtc, not in hibmc_kms_init().
> -connector is initialized inside encoder, not in hibmc_kms_init().
> -remove plane/crtc/encoder/connector from hibmc_drm_private struct.
> -call drm_atomic_helper_suspend/resume in hibmc_pm_suspend/resume.
> -remove these empty stubs because caller will do NULL check.
> hibmc_plane_atomic_disable
> hibmc_crtc_atomic_check
> hibmc_encoder_disable
> hibmc_encoder_enable
> hibmc_encoder_atomic_check
> -clean up in all error paths of creating driver-private framebuffer.
>
> Changes in v6:
> -remove the embedded framebuffer and use a pointer of hibmc_framebuffer
> instead.
> -remove the deprecated drm_framebuffer_unregister_private(),
> drm_framebuffer_unreference() will be called in hibmc_fbdev_destroy().
> -uninstall irq in hibmc_unload().
>
> Changes in v5:
> -rebase on v4.9-rc2.
> -replace drm_fb_helper_set_suspend with drm_fb_helper_set_suspend_unlocked.
> and remove redundant console_lock and console_unlock.
>
> Changes in v4:
> -remove unused include files, and include header file when it is needed.
> -remove unused FLAG in Kconfig: DRM_GEM_CMA_HELPER/DRM_KMS_CMA_HELPER.
> -remove drm_helper_disable_unused_functions, since we use DRIVER_ATOMIC.
>
> Changes in v3:
> -enable KMS, in v2, only fbdev is enabled.
> -management video memory with ttm.
> -add vblank interrupt.
> -remove drm_connector_register_all() and drm_connector_unregister_all().
> -I have a basic test with igt.
>
> Changes in v2:
> -Remove self-defined macros for bit operations.
> -Remove unused register.
> -Replace those deprecated functions with new version of them.
> -use drm_connector_register_all() to register connector after
> drm_dev_register().
>
> The patch v2 is at
> https://lists.freedesktop.org/archives/dri-devel/2016-May/108661.html
>
> Rongrong Zou (7):
> drm/hisilicon/hibmc: Add hisilicon hibmc drm master driver
> drm/hisilicon/hibmc: Add video memory management
> drm/hisilicon/hibmc: Add support for frame buffer
> drm/hisilicon/hibmc: Add support for display engine
> drm/hisilicon/hibmc: Add support for VDAC
> drm/hisilicon/hibmc: Add support for vblank interrupt
> MAINTAINERS: Update HISILICON DRM entries
>
> MAINTAINERS | 1 +
> drivers/gpu/drm/hisilicon/Kconfig | 1 +
> drivers/gpu/drm/hisilicon/Makefile | 1 +
> drivers/gpu/drm/hisilicon/hibmc/Kconfig | 9 +
> drivers/gpu/drm/hisilicon/hibmc/Makefile | 4 +
> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 477 ++++++++++++++++++
> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 456 ++++++++++++++++++
> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 114 +++++
> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c | 267 +++++++++++
> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h | 196 ++++++++
> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 147 ++++++
> drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 558 ++++++++++++++++++++++
> 12 files changed, 2231 insertions(+)
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Kconfig
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/Makefile
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
>
> --
> 1.9.1
>
^ permalink raw reply
* wdt, gpio: move arch_initcall into subsys_initcall ?
From: Heiko Schocher @ 2016-11-17 7:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ee9824b8-f09f-3817-8893-8121c9fb9eb1@roeck-us.net>
Hello Guenter, Vladimir,
Sorry for the late response, but I was "on the road" ...
Am 15.11.2016 um 14:46 schrieb Guenter Roeck:
> On 11/15/2016 03:32 AM, Vladimir Zapolskiy wrote:
>> On 11/15/2016 01:10 PM, Vladimir Zapolskiy wrote:
>>> Hello Heiko,
>>>
>>> On 11/15/2016 12:20 PM, Heiko Schocher wrote:
>>>> Hello,
>>>>
>>>> commit e188cbf7564f: "gpio: mxc: shift gpio_mxc_init() to subsys_initcall level"
>>>> moves the gpio initialization of the mxc gpio driver
>>>> from the arch_initcall level into subsys_initcall level.
>>>>
>>>> This leads now on mxc boards, which use a gpio wdt driver
>>>> and the CONFIG_GPIO_WATCHDOG_ARCH_INITCALL option enabled,
>>>> to unwanted driver probe deferrals during kernel boot.
>>>>
>>>> I see this currently on an imx6 based board (which has unfortunately
>>>> 3 WDT: imx6 internal (disabled), gpio wdt and da9063 WDT ...).
>>>>
>>>> Also a side effect from above commit is, that the da9063 WDT driver
>>>> is now probed before the gpio WDT driver ... so /dev/watchdog now
>>>> does not point to the gpio_wdt, instead it points to the da9063 WDT.
>>>>
>>>> So there are 2 solutions possible:
>>>>
>>>> - add a CONFIG_GPIO_MCX_ARCH_INITCALL option
>>>> in drivers/gpio/gpio-mxc.c like for the gpio_wdt.c driver?
>>>
>>> in my opinion this is overly heavy solution and it might be
>>> better to avoid it if possible.
>>>
>>> I would rather prefer to reconsider GPIO_WATCHDOG_ARCH_INITCALL
>>> usage in the watchdog driver.
>>>
>>> Moreover adding this proposed GPIO_MCX_ARCH_INITCALL to call
>>> the driver on arch level will result in deferring the GPIO driver.
>>>
>>>> But how can we guarantee, that first the gpio driver and then
>>>> the gpio_wdt driver gets probed?
>>>>
>>>> - move the arch_initcall in gpio_wdt.c into a subsys_initcall
>>>> (Tested this, and the probe dereferral messages are gone ...)
>>>>
>>>> But this may results in problems on boards, which needs an early
>>>> trigger on an gpio wdt ...
>>>
>>> The level of "earliness" can not be defined in absolute time value
>>> in any case, why decreasing the init level of the watchdog driver
>>> to subsys level can cause problems? For that there should exist
>>> some kind of a dependency on IC or PCB hardware level, can you
>>> name it please?
On the current problem, there is no dependency on PCB, but I know
of watchdogs triggered through a gpio pin, which must triggered < 1 second
and subsys_initcall is too late for this. I think, this was the reason
for introducing the CONFIG_GPIO_WATCHDOG_ARCH_INITCALL option ...
>>> Also please note that more than a half of all GPIO drivers settle
>>> on subsys or later initcall level, this means that there is
>>> an expected GPIO watchdog driver deferral for all of them.
>>
>> Please find two more late notes though.
>>
>>> I propose to send two patches for review:
>>>
>>> 1. remove GPIO_WATCHDOG_ARCH_INITCALL option completely and decouple
>>> module_platform_driver() into arch_initcall() and module_exit()
>>> unconditionally.
>>>
>>> 2. change arch_initcall() in the watchdog driver to subsys_initcall().
>>> This change removes probe deferrals on boot, when the driver is
>>> used with the most of the GPIO controllers.
>>
>> Alternatively commit 5e53c8ed813d ("watchdog: gpio_wdt: Add option for
>> early registration") can be reverted and then module_platform_driver()
>> is decoupled into subsys_initcall() and module_exit() as its replacement.
>>
> Sure, only the reason for that was that there are situations where
> subsys_initcall() was too late. Also, when using arch_initcall() only,
> we get deferrals again, which is apparently hated by many and a reason
> for all those "avoid probe deferrals" patches.
Exactly. And I wonder, if this boards, who need this early trigger,
work with current kernel ? (Or this boards use a gpio driver, which is
not in subsys_initcall level ...)
>> And also please note that since quite many GPIO controller drivers
>> live on initcall levels after subsys_initcall(), the solution won't
>> let to avoid watchdog driver deferrals totally, this should be accepted.
>>
> ... except for others it isn't, and we are back to square one.
>
> GPIO_WATCHDOG_ARCH_INITCALL was intended to be only used in situations
> where needed. Why is it used here in the first place if that is not
> the case ?
Heh, good question ...
"/dev/watchdog" is in systemd hard-coded, see:
https://github.com/systemd/systemd/blob/dd8352659c9428b196706d04399eec106a8917ed/src/shared/watchdog.c#L86
http://0pointer.de/blog/projects/watchdog.html
https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html
We have 2 WDT driver enabled on the board (GPIO WDT and the DA9063 WDT).
If both WDTs are in the subsys_initall level, first the da9063 wdt
gets probed, and so "/dev/watchdog" points to the da9063 wdt, but
we want to use the GPIO wdt as "/dev/watchdog" device.
Now, why not simple disabling the da9063 wdt ?
We could not disable the da9063 wdt functionallity, because we need
for a clean reboot that the da9063_wdt_restart() is called in the
restart sequence ... which is registered in the wdt driver:
static const struct watchdog_ops da9063_watchdog_ops = {
[...]
.restart = da9063_wdt_restart,
};
Is there a possbility to register this restart function may somewhere
else? It seems, that this is not a WDT functionallity ...
bye,
Heiko
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply
* [PATCH next] arm64: remove "SMP: Total of %d processors activated." message
From: Kefeng Wang @ 2016-11-17 7:32 UTC (permalink / raw)
To: linux-arm-kernel
There is a common SMP boot message in generic code on all arches,
kill "SMP: Total of %d processors activated." in smp_cpus_done()
on arm64.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
Boot message on qemu.
[ 0.375116] smp: Brought up 1 node, 8 CPUs
[ 0.383749] SMP: Total of 8 processors activated.
arch/arm64/kernel/smp.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index cb87234..9db4a95 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -428,7 +428,6 @@ static void __init hyp_mode_check(void)
void __init smp_cpus_done(unsigned int max_cpus)
{
- pr_info("SMP: Total of %d processors activated.\n", num_online_cpus());
setup_cpu_features();
hyp_mode_check();
apply_alternatives_all();
--
1.7.12.4
^ permalink raw reply related
* [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family flash
From: Krzeminski, Marcin (Nokia - PL/Wroclaw) @ 2016-11-17 7:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161116171058.GA21300@Cayman.am.freescale.net>
> -----Original Message-----
> From: Han Xu [mailto:xhnjupt at gmail.com]
> Sent: Wednesday, November 16, 2016 6:11 PM
> To: Krzeminski, Marcin (Nokia - PL/Wroclaw)
> <marcin.krzeminski@nokia.com>
> Cc: Yunhui Cui <B56489@freescale.com>; Yunhui Cui <yunhui.cui@nxp.com>;
> David Woodhouse <dwmw2@infradead.org>; linux-kernel at vger.kernel.org;
> linux-mtd at lists.infradead.org; han.xu at freescale.com; Brian Norris
> <computersforpeace@gmail.com>; jagannadh.teki at gmail.com; linux-arm-
> kernel at lists.infradead.org; Yao Yuan <yao.yuan@nxp.com>
> Subject: Re: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family
> flash
>
> On Thu, Sep 15, 2016 at 06:50:55AM +0000, Krzeminski, Marcin (Nokia -
> PL/Wroclaw) wrote:
> > Hello,
> >
> > > -----Original Message-----
> > > From: linux-mtd [mailto:linux-mtd-bounces at lists.infradead.org] On
> > > Behalf Of Han Xu
> > > Sent: Wednesday, September 14, 2016 9:49 PM
> > > To: Yunhui Cui <B56489@freescale.com>
> > > Cc: Yunhui Cui <yunhui.cui@nxp.com>; David Woodhouse
> > > <dwmw2@infradead.org>; linux-kernel at vger.kernel.org; linux-
> > > mtd at lists.infradead.org; han.xu at freescale.com; Brian Norris
> > > <computersforpeace@gmail.com>; jagannadh.teki at gmail.com; linux-
> arm-
> > > kernel at lists.infradead.org; Yao Yuan <yao.yuan@nxp.com>
> > > Subject: Re: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S
> > > family flash
> > >
> > > On Thu, Aug 18, 2016 at 2:38 AM, Yunhui Cui <B56489@freescale.com>
> > > wrote:
> > > > From: Yunhui Cui <yunhui.cui@nxp.com>
> > > >
> > > > With the physical sectors combination, S25FS-S family flash
> > > > requires some special operations for read/write functions.
> > > >
> > > > Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
> > > > ---
> > > > drivers/mtd/spi-nor/spi-nor.c | 56
> > > > +++++++++++++++++++++++++++++++++++++++++++
> > > > 1 file changed, 56 insertions(+)
> > > >
> > > > diff --git a/drivers/mtd/spi-nor/spi-nor.c
> > > > b/drivers/mtd/spi-nor/spi-nor.c index d0fc165..495d0bb 100644
> > > > --- a/drivers/mtd/spi-nor/spi-nor.c
> > > > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > > > @@ -39,6 +39,10 @@
> > > >
> > > > #define SPI_NOR_MAX_ID_LEN 6
> > > > #define SPI_NOR_MAX_ADDR_WIDTH 4
> > > > +/* Added for S25FS-S family flash */
> > > > +#define SPINOR_CONFIG_REG3_OFFSET 0x800004
> > > > +#define CR3V_4KB_ERASE_UNABLE 0x8 #define
> > > > +SPINOR_S25FS_FAMILY_EXT_JEDEC 0x81
> > > >
> > > > struct flash_info {
> > > > char *name;
> > > > @@ -78,6 +82,7 @@ struct flash_info { };
> > > >
> > > > #define JEDEC_MFR(info) ((info)->id[0])
> > > > +#define EXT_JEDEC(info) ((info)->id[5])
> > > >
> > > > static const struct flash_info *spi_nor_match_id(const char
> > > > *name);
> > > >
> > > > @@ -899,6 +904,7 @@ static const struct flash_info spi_nor_ids[] = {
> > > > */
> > > > { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64,
> > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128,
> > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > + { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512,
> > > > + 0)},
> > > > { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
> > > > { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512,
> > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256,
> > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, @@ -1036,6
> +1042,50
> > > @@ static const struct flash_info *spi_nor_read_id(struct spi_nor
> > > *nor)
> > > > return ERR_PTR(-ENODEV);
> > > > }
> > > >
> > > > +/*
> > > > + * The S25FS-S family physical sectors may be configured as a
> > > > + * hybrid combination of eight 4-kB parameter sectors
> > > > + * at the top or bottom of the address space with all
> > > > + * but one of the remaining sectors being uniform size.
> > > > + * The Parameter Sector Erase commands (20h or 21h) must
> > > > + * be used to erase the 4-kB parameter sectors individually.
> > > > + * The Sector (uniform sector) Erase commands (D8h or DCh)
> > > > + * must be used to erase any of the remaining
> > > > + * sectors, including the portion of highest or lowest address
> > > > + * sector that is not overlaid by the parameter sectors.
> > > > + * The uniform sector erase command has no effect on parameter
> > > sectors.
> > > > + */
> > > > +static int spansion_s25fs_disable_4kb_erase(struct spi_nor *nor) {
> > > > + u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET;
> > > > + u8 cr3v = 0x0;
> > > > + int ret = 0x0;
> > > > +
> > > > + nor->cmd_buf[2] = cr3v_addr >> 16;
> > > > + nor->cmd_buf[1] = cr3v_addr >> 8;
> > > > + nor->cmd_buf[0] = cr3v_addr >> 0;
> > > > +
> > > > + ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
> > > > + if (ret)
> > > > + return ret;
> > > > + if (cr3v & CR3V_4KB_ERASE_UNABLE)
> > > > + return 0;
> > > > + ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
> > > > + if (ret)
> > > > + return ret;
> > > > + cr3v = CR3V_4KB_ERASE_UNABLE;
> > > > + nor->program_opcode = SPINOR_OP_SPANSION_WRAR;
> > > > + nor->write(nor, cr3v_addr, 1, &cr3v);
> > > > +
> > > > + ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
> > > > + if (ret)
> > > > + return ret;
> > > > + if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
> > > > + return -EPERM;
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
> > > > size_t *retlen, u_char *buf) { @@ -1361,6
> > > > +1411,12 @@ int spi_nor_scan(struct spi_nor *nor, const char
> > > > +*name,
> > > enum read_mode mode)
> > > > spi_nor_wait_till_ready(nor);
> > > > }
> > > >
> > > > + if (EXT_JEDEC(info) == SPINOR_S25FS_FAMILY_EXT_JEDEC) {
> > > > + ret = spansion_s25fs_disable_4kb_erase(nor);
> > > > + if (ret)
> > > > + return ret;
> > > > + }
> > > > +
> > > > if (!mtd->name)
> > > > mtd->name = dev_name(dev);
> > > > mtd->priv = nor;
> > > > --
> > > > 2.1.0.27.g96db324
> > > >
> > > >
> > > Hi Brian, I will ack this change but still feel it's kind of hacking code.
> > >
> > > Acked-by: Han xu <han.xu@nxp.com>
> >
> > I am new on the list so I am not sure if this topic has been discussed.
> > Generally our product functionality relay on those 4KiB sectors.
> > I know that this hack is already in u-boot, but if you mainstream this
> > you will force users of those 4KiB sectors to do hack the hack...
> > I believe the proper solution here is to use erase regions
> > functionality, I send and RFS about that some time ago.
>
> Do you mind to send me a link for reference?
>
Han,
Sorry, It seem I have not posted erase region changes (only those regarding DUAL/QUAD I/O).
Generally, in this flash you need to create 3 erase regions (because in FS-S family support only
4KiB erase on parameters sector - eg. 1.2.2.4 in S25FS512S). In my case regions are:
1. 0-32KiB (8*4KiB) - 4K_ERASE (0x20/0x21)
2. 32 - 256 - SE_CMD (0xd8/0xdc)
3. Rest of the flash SE_CMD (0xd8/0xdc)
To erase whole flash you can also use CHIP_ERASE_CMD (0x60/0xC7) command, you just
need to add one more mtd partition that will cover whole flash.
Thanks,
Marcin
> Sincerely,
> Han XU
>
> >
> > Thanks,
> > Marcin
> >
> > > > ______________________________________________________
> > > > Linux MTD discussion mailing list
> > > > http://lists.infradead.org/mailman/listinfo/linux-mtd/
> > >
> > >
> > >
> > > --
> > > Sincerely,
> > >
> > > Han XU
> > >
> > > ______________________________________________________
> > > Linux MTD discussion mailing list
> > > http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
* ILP32 for ARM64 - testing with lmbench
From: Zhangjian (Bamvor) @ 2016-11-17 7:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <266952F2-53F5-4D5E-83F0-6C8203092F67@linaro.org>
Hi, Maxim
On 2016/11/17 13:02, Maxim Kuvyrkov wrote:
> Hi Bamvor,
>
> I'm surprised that you see this much difference from ILP32 patches on SPEC CPU2006int at all. The SPEC CPU2006 benchmarks spend almost no time in the kernel syscalls. I can imagine memory, TLB, and cache handling in the kernel could affect CPU2006 benchmarks. Do ILP32 patches touch code in those areas?
>
> Other than that, it would be interesting to check what the variance is between the 3 iterations of benchmark runs. Could you check what relative standard deviation is between the 3 iterations -- (STDEV(RUN1, RUN2, RUN3) / RUNselected)?
>
> For reference, in my [non-ILP32] benchmarking I see 1.1% for 401.bzip2, 0.8% for 429.mcf, 0.2% for 456.hmmer, and 0.1% for 462.libquantum.
Here is my result:
ILP32_merged ILP32_unmerged
401.bzip2 0.31% 0.26%
429.mcf 1.61% 1.36%
456.hmmer 1.37% 1.57%
462.libquantum 0.29% 0.28%
Regards
Bamvor
>
> --
> Maxim Kuvyrkov
> www.linaro.org
>
>
>
>> On Nov 17, 2016, at 7:28 AM, Zhangjian (Bamvor) <bamvor.zhangjian@huawei.com> wrote:
>>
>> Hi, all
>>
>> I test specint of aarch64 LP64 when aarch32 el0 disable/enabled respectively
>> and compare with ILP32 unmerged kernel(4.8-rc6) in our arm64 board. I found
>> that difference(ILP32 disabled/ILP32 unmerged) is bigger when aarch32 el0 is
>> enabled, compare with aarch32 el0 disabled kernel. And bzip2, mcg, hmmer,
>> libquantum are the top four differences[1]. Note that bigger is better in
>> specint test.
>>
>> In order to make sure the above results, I retest these four testcases in
>> reportable way(reference the command in the end). The result[2] show that
>> libquantum decrease -2.09% after ILP32 enabled and aarch32 on. I think it is in
>> significant.
>>
>> The result of lmbench is not stable in my board. I plan to dig it later.
>>
>> [1] The following test result is tested through --size=ref --iterations=3.
>> 1.1 Test when aarch32_el0 is enabled.
>> ILP32 disabled base line
>> 400.perlbench 100.00% 100%
>> 401.bzip2 99.35% 100%
>> 403.gcc 100.26% 100%
>> 429.mcf 102.75% 100%
>> 445.gobmk 100.00% 100%
>> 456.hmmer 95.66% 100%
>> 458.sjeng 100.00% 100%
>> 462.libquantum 100.00% 100%
>> 471.omnetpp 100.59% 100%
>> 473.astar 99.66% 100%
>> 483.xalancbmk 99.10% 100%
>>
>> 1.2 Test when aarch32_el0 is disabled
>> ILP32 disabled base line
>> 400.perlbench 100.22% 100%
>> 401.bzip2 100.95% 100%
>> 403.gcc 100.20% 100%
>> 429.mcf 100.76% 100%
>> 445.gobmk 100.36% 100%
>> 456.hmmer 97.94% 100%
>> 458.sjeng 99.73% 100%
>> 462.libquantum 98.72% 100%
>> 471.omnetpp 100.86% 100%
>> 473.astar 99.15% 100%
>> 483.xalancbmk 100.08% 100%
>>
>> [2] The following test result is tested through: runspec --config=my.cfg --size=test,train,ref --noreportable --tune=base,peak --iterations=3 bzip2 mcf hmmer libquantum
>> 2.1 Test when aarch32_el0 is enabled.
>> ILP32_enabled base line
>> 401.bzip2 100.82% 100%
>> 429.mcf 100.18% 100%
>> 456.hmmer 99.64% 100%
>> 462.libquantum 97.91% 100%
>>
>> Regards
>>
>> Bamvor
>>
>> On 2016/10/28 20:46, Yury Norov wrote:
>>> [Add Steve Ellcey, thanks for testing on ThunderX]
>>>
>>> Lmbench-3.0-a9 testing is performed on ThunderX machine to check that
>>> ILP32 series does not add performance regressions for LP64. Test
>>> summary is in the table below. Our measurements doesn't show
>>> significant performance regression of LP64 if ILP32 code is merged,
>>> both enabled or disabled.
>>>
>>> ILP32 enabled ILP32 disabled Standard Kernel
>>> null syscall 0.1066 0.1121 0.1121
>>> 95.09% 100.00%
>>>
>>> stat 1.3947 1.3814 1.3864
>>> 100.60% 99.64%
>>>
>>> fstat 0.4459 0.4344 0.4524
>>> 98.56% 96.02%
>>>
>>> open/close 4.0606 4.0411 4.0453
>>> 100.38% 99.90%
>>>
>>> read 0.4819 0.5014 0.5014
>>> 96.11% 100.00%
>>>
>>> Tested with linux 4.8 because 4.9-rc1 is not fixed yet for ThunderX.
>>> Other system details below.
>>>
>>> Yury.
>>>
>>> ubuntu at crb6:~$ uname -a
>>> Linux crb6 4.8.0+ #3 SMP Thu Oct 27 11:01:32 PDT 2016 aarch64 aarch64 aarch64 GNU/Linux
>>>
>>> ubuntu at crb6:~$ cat /proc/meminfo
>>> MemTotal: 132011948 kB
>>> MemFree: 131442672 kB
>>> MemAvailable: 130695764 kB
>>> Buffers: 15696 kB
>>> Cached: 88088 kB
>>> SwapCached: 0 kB
>>> Active: 82760 kB
>>> Inactive: 41336 kB
>>> Active(anon): 20880 kB
>>> Inactive(anon): 8576 kB
>>> Active(file): 61880 kB
>>> Inactive(file): 32760 kB
>>> Unevictable: 0 kB
>>> Mlocked: 0 kB
>>> SwapTotal: 128920572 kB
>>> SwapFree: 128920572 kB
>>> Dirty: 0 kB
>>> Writeback: 0 kB
>>> AnonPages: 20544 kB
>>> Mapped: 19780 kB
>>> Shmem: 9060 kB
>>> Slab: 78804 kB
>>> SReclaimable: 27372 kB
>>> SUnreclaim: 51432 kB
>>> KernelStack: 8336 kB
>>> PageTables: 820 kB
>>> NFS_Unstable: 0 kB
>>> Bounce: 0 kB
>>> WritebackTmp: 0 kB
>>> CommitLimit: 194926544 kB
>>> Committed_AS: 256324 kB
>>> VmallocTotal: 135290290112 kB
>>> VmallocUsed: 0 kB
>>> VmallocChunk: 0 kB
>>> AnonHugePages: 0 kB
>>> ShmemHugePages: 0 kB
>>> ShmemPmdMapped: 0 kB
>>> CmaTotal: 0 kB
>>> CmaFree: 0 kB
>>> HugePages_Total: 0
>>> HugePages_Free: 0
>>> HugePages_Rsvd: 0
>>> HugePages_Surp: 0
>>> Hugepagesize: 2048 kB
>>>
>>> ubuntu at crb6:~$ cat /proc/cpuinfo
>>> processor : 0
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 1
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 2
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 3
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 4
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 5
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 6
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 7
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 8
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 9
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 10
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 11
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 12
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 13
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 14
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 15
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 16
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 17
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 18
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 19
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 20
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 21
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 22
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 23
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 24
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 25
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 26
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 27
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 28
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 29
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 30
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 31
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 32
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 33
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 34
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 35
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 36
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 37
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 38
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 39
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 40
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 41
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 42
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 43
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 44
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 45
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 46
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>> processor : 47
>>> BogoMIPS : 200.00
>>> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
>>> CPU implementer : 0x43
>>> CPU architecture: 8
>>> CPU variant : 0x1
>>> CPU part : 0x0a1
>>> CPU revision : 0
>>>
>>
>
^ permalink raw reply
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