[PATCH] cpuidle: coupled: fix the potensial race condition and deadlock

2012-12-02 Thread Joseph Lo
Considering the chance that two CPU come into cpuidle_enter_state_coupled at
very close time. The 1st CPU increases the waiting count and the 2nd CPU do the
same thing right away. The 2nd CPU found the 1st CPU already in waiting then
prepare to poke it.

Before the 2nd CPU to poke 1st CPU, the 1st found the waiting count already same
with cpu_online count. So the 1st won't go into waiting loop and the 2nd CPU
didn't poke it yet. The 1st CPU will go into ready loop directly.

Then the 2nd CPU set up the couple_cpuidle_mask for 1st CPU and poke it. But the
1st CPU already lost the chance to handle the poke and clear the
couple_cpuidle_mask. Now whole MPcore are alredy to be coupled. The MPcore will
go into the power saving idle mode.

Because the poke was be implemented as a smp_call_function_single, it's a
software intrrupt of IPI_SINGLE_FUNC. If the power saving idle mode of the
platform can't retain the software interrupt of power saving idle mode, (e.g.
Tegra's powerd-down idle mode will shut off cpu power that include the power of
GIC) the software interrupt will got lost.

When the CPU resumed from the power saving idle mode and the system still keep
idle, it will go into idle mode again immediately. Because the
smp_call_function_single not allow the same function be called for the same
cpu twice, or it will got a lock. So the couple_cpuidle_mask can't be cleared
by 1st CPU, the 2nd CPU also can't poke it again. Then the deadlock happens
here.

The fix here used different wake up mechanism. Because there are already two
loops and a gloable variable ready_waiting_counts to sync the status of
MPcore to coupled state, the coupled_cpuidle_mask was not really necessary.
Just waking up the CPU from waiting and checking if the CPU need resched at
outside world to take the CPU out of idle are enough. And this fix didn't
modify the original behavior of coupled cpuidle framework. It should still
compitable with the origianal. The cpuidle driver that already applies
coupled cpuidle not need to change as well.

Cc: Colin Cross ccr...@android.com
Signed-off-by: Joseph Lo jose...@nvidia.com
---
Please check the detail sequence about how race condition and deadlock
be happened below:
It could be reproduced on Tegra20 and Tegra30.
(Suppose the last two cpu came into coupled_cpuidle_state at very close time)

CPU_0   CPU_1
cpuidle_enter_state_coupled
cpuidle_enter_state_coupled
1.increase waiting count
1. increase waiting count
 same time frame ---
2.before went into waiting
  loop, check the waiting
  count first
  2.1 the waiting count
   was same with online
   count
  2.2 so it won't go into
   waiting loop
2.in the procedure to prepare to send an
 smp_call_function_single to wake up CPU_0
 next time frame ---
3.before go into ready loop
  3.1 it will enable_irq
  3.2 check if there is any
IPI
  3.3 if yes, clear the coupled_mask
  3.4 then disable_irq
3. trigger the IPI to CPU_0
 3.1 set up the coupled_mask for CPU_0
 3.2 sent IPI to CPU_0
4. the IPI_SINGLE_FUNC been triggered from CPU_1 to CPU_0 and the coupled_mask
  of CPU_0 been set up
  4.1 but the CPU_0 miss the IPI and the chance to clear coupled_mask
 next time frame ---
5. MPCores went into ready loop and been coupled
6. go into power saving idle mode
   (For Tegra, it's means the vdd_cpu rail be shut off. The GIC be powered off
and the SW_INT(IPI) couldn't be retained.)
7. After the resume of power saving idle mode, the coupled_mask of CPU_0 not
   been cleared.
8. return to kernel

If the system still idle, it will come back to idle immediately.

CPU_0   CPU_1
cpuidle_enter_state_coupled
cpuidle_enter_state_coupled
1. set itself to waiting
2. go into waiting loop
3. check the coupled_mask been
  set or not
  3.1 enable_irq
  3.2 waiting for the coupled_mask
be cleared

1. found CPU_0 in waiting
2. prepare an IPI to poke CPU_0
  2.1 check the coupled_mask of CPU_0
  2.2 because it had been set
  2.3 so it didn't trigger and
smp_call_function_single to CPU_0 again
3. then go into ready loop

4. because there is no irq of
  IPI_SINGLE_FUNC be triggered

Re: CPU hotplug hang due to swap: make each swap partition have one address_space

2013-02-03 Thread Joseph Lo
On Mon, 2013-02-04 at 10:36 +0800, Shaohua Li wrote:
 On Fri, Feb 01, 2013 at 10:02:33PM -0700, Stephen Warren wrote:
  Shaohua,
  
  In next-20130128, commit 174f064 swap: make each swap partition have
  one address_space (from the mm/akpm tree) appears causes a hang/RCU
  stall for me when hot-unplugging a CPU.
 
 does this one work for you?
 http://marc.info/?l=linux-mmm=135929599505624w=2
 Or try a more recent linux-next. The patch is in akpm's tree.
 
Hi Shaohua,

The patch you pointed out did fix the issue. Just verified on Tegra
device.

Thanks,
Joseph


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/5] cpufreq: star/stop cpufreq timers on cpu hotplug

2013-01-29 Thread Joseph Lo
On Wed, 2013-01-30 at 12:52 +0800, Viresh Kumar wrote:
 Hi Fabio,
 
 Sorry for waking up very late :)
 
 The reason why i am starting this thread again is due to problem
 reported by Joseph,
 with latest linux-next/master branch (which contains few big patches
 from me :) ):
 
After Viresh point me out what patch may cause the issue that I met
below, I also try to just revert this patch on linux-next. Then
everything that may trigger to disable_nonboot_cpus or hotplug back to
normal. So just reverting this patch also fix the issues I saw.
FYI.

Thanks,
Joseph

 Reboot is giving following to him:
 
 * Will now halt
 [ 193.756068] Disabling non-boot CPUs...
 [ 193.760088] BUG: scheduling while atomic: halt/780/0x0002
 [ 193.765845] Modules linked in: brcmfmac brcmutil
 [ 193.770613] [c0014990] (unwind_backtrace+0x0/0xf8) from [c0049510]
 (__schedule_bug+0x44/0x5c)
 [ 193.779548] [c0049510] (__schedule_bug+0x44/0x5c) from [c04fa320]
 (__schedule+0x688/0x6ec)
 [ 193.788206] [c04fa320] (__schedule+0x688/0x6ec) from [c04fa75c]
 (schedule_preempt_disabled+0x24/0x34)
 [ 193.797811] [c04fa75c] (schedule_preempt_disabled+0x24/0x34) from
 [c04f916c] (__mutex_lock_slowpath+0x170/0x34c)
 [ 193.808367] [c04f916c] (__mutex_lock_slowpath+0x170/0x34c) from
 [c04f9354] (mutex_lock+0xc/0x24)
 [ 193.817554] [c04f9354] (mutex_lock+0xc/0x24) from [c04f1cdc]
 (unregister_cpu_notifier+0xc/0x24)
 [ 193.826640] [c04f1cdc] (unregister_cpu_notifier+0xc/0x24) from
 [c033a8a4] (cpufreq_governor_dbs+0x118/0x614)
 [ 193.836866] [c033a8a4] (cpufreq_governor_dbs+0x118/0x614) from
 [c033747c] (__cpufreq_governor+0x58/0xc0)
 [ 193.846737] [c033747c] (__cpufreq_governor+0x58/0xc0) from
 [c0339104] (__cpufreq_remove_dev.clone.7+0x58/0x320)
 [ 193.857207] [c0339104] (__cpufreq_remove_dev.clone.7+0x58/0x320)
 from [c04f7958] (cpufreq_cpu_callback+0x8c/0x9c)
 [ 193.867850] [c04f7958] (cpufreq_cpu_callback+0x8c/0x9c) from
 [c0044f4c] (notifier_call_chain+0x44/0x84)
 [ 193.877623] [c0044f4c] (notifier_call_chain+0x44/0x84) from
 [c0026e24] (__cpu_notify+0x2c/0x48)
 [ 193.886704] [c0026e24] (__cpu_notify+0x2c/0x48) from [c04f1b08]
 (_cpu_down+0xb0/0x23c)
 [ 193.895004] [c04f1b08] (_cpu_down+0xb0/0x23c) from [c00270ec]
 (disable_nonboot_cpus+0x68/0x104)
 [ 193.904089] [c00270ec] (disable_nonboot_cpus+0x68/0x104) from
 [c0034fbc] (kernel_power_off+0x24/0x48)
 [ 193.913688] [c0034fbc] (kernel_power_off+0x24/0x48) from
 [c0035810] (sys_reboot+0x104/0x1e0)
 [ 193.922517] [c0035810] (sys_reboot+0x104/0x1e0) from [c000e520]
 (ret_fast_syscall+0x0/0x30)
 
 
 And the crash log show this patch of yours somewhere :)
 
 First question: Is this patch still required? Because following patch from me 
 is
 sending a STOP/START to governors on cpu hot-[un]plug ?
 
 commit dbcb63407c095af73f3464767e00902cdee55e8b
 Author: Viresh Kumar viresh.ku...@linaro.org
 Date:   Sat Jan 12 05:14:39 2013 +
 
 cpufreq: Notify governors when cpus are hot-[un]plugged
 
 
 For me, the answer is NO.
 
 Over that, i tried these patches on ARM bigLITTLE TC2 (3 A7's  and 2 A15's) 
 and
 my system wasn't booting at all for ondemand governor. Reverting your patch 
 does
 fix the issue:
 
 [2.613573] arm_big_little: bL_cpufreq_init: Initialized, cpu: 0, cluster 0
 [2.635436] arm_big_little: bL_cpufreq_init: Initialized, cpu: 2, cluster 1
 [   23.650184] INFO: rcu_sched self-detected stall on CPU { 0}
 (t=2100 jiffies g=4294967088 c=4294967087 q=10)
 [   23.679664] Backtrace for cpu 0 (current):
 [   23.680239] INFO: rcu_sched detected stalls on CPUs/tasks: { 0}
 (detected by 2, t=2103 jiffies, g=4294967088, c=4294967087, q=10)
 [   23.726839] [c0014020] (unwind_backtrace+0x0/0xf8) from
 [c0012f60] (smp_send_all_cpu_backtrace+0x60/0xcc)
 [   23.756545] [c0012f60] (smp_send_all_cpu_backtrace+0x60/0xcc)
 from [c008232c] (rcu_pending+0x2c8/0x63c)
 [   23.785731] [c008232c] (rcu_pending+0x2c8/0x63c) from
 [c0083854] (rcu_check_callbacks+0x7c/0x148)
 [   23.813358] [c0083854] (rcu_check_callbacks+0x7c/0x148) from
 [c002d1e0] (update_process_times+0x38/0x68)
 [   23.842808] [c002d1e0] (update_process_times+0x38/0x68) from
 [c0066b00] (tick_sched_handle+0x48/0x54)
 [   23.871472] [c0066b00] (tick_sched_handle+0x48/0x54) from
 [c0066d6c] (tick_sched_timer+0x44/0x74)
 [   23.899098] [c0066d6c] (tick_sched_timer+0x44/0x74) from
 [c00416d8] (__run_hrtimer+0x84/0x1b4)
 [   23.925940] [c00416d8] (__run_hrtimer+0x84/0x1b4) from
 [c004224c] (hrtimer_interrupt+0x108/0x2d4)
 [   23.953563] [c004224c] (hrtimer_interrupt+0x108/0x2d4) from
 [c0013990] (arch_timer_handler_virt+0x30/0x38)
 [   23.983530] [c0013990] (arch_timer_handler_virt+0x30/0x38) from
 [c007e41c] (handle_percpu_devid_irq+0x74/0x110)
 [   24.014799] [c007e41c] (handle_percpu_devid_irq+0x74/0x110) from
 [c007ac8c] (generic_handle_irq+0x20/0x30)
 [   24.044765] [c007ac8c] (generic_handle_irq+0x20/0x30) from
 [c000e9f4] (handle_IRQ+0x38/0x94)
 [   24.071085] [c000e9f4] (handle_IRQ+0x38/0x94) from [c0008570]
 

Re: [PATCH v3 0/9] Migrate Tegra to common clock framework

2013-01-04 Thread Joseph Lo
On Fri, 2013-01-04 at 17:40 +0800, Prashant Gaikwad wrote:
 This patchset does following:
 1. Decompose single tegra clock structure into multiple clocks.
 2. Try to use standard clock types supported by common clock framework.
 3. Use dynamic initialization.
 4. Move all clock code to drivers/clk/tegra from mach-tegra.
 5. Add device tree support for Tegra20 and Tegra30 clocks.
 6. Remove all legacy clock code from mach-tegra.
 
 Tested on Tegra30 (Cardhu) and Tegra20 (Ventana).
 
 Changes from v2:
 Removed APB MISC node.
 Fixed some issues reported by Joseph Lo.
 Added function to read chip id revision register.
 
 Changes from v1:
 Rebased on linux-next for 20121224.
 
 Prashant Gaikwad (8):
   ARM: tegra: Add function to read chipid
   clk: tegra: Add tegra specific clocks
   arm: tegra: Move tegra_cpu_car.h to linux/clk/tegra.h
   ARM: Tegra: Define Tegra30 CAR binding
   clk: tegra: add clock support for tegra20
   clk: tegra: add clock support for tegra30
   arm: tegra: Migrate to new clock code
   arm: tegra: Remove legacy clock code
 
 Stephen Warren (1):
   ARM: tegra: Define Tegra20 CAR binding
 

Good job, Prashant. :-)

This series :
Tested-by: Joseph Lo jose...@nvidia.com


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/7] ARM: dt: tegra20: Add clock information

2013-01-04 Thread Joseph Lo
On Fri, 2013-01-04 at 17:46 +0800, Prashant Gaikwad wrote:
 Add clock information to device nodes.
 
 Signed-off-by: Prashant Gaikwad pgaik...@nvidia.com
 ---
 Tested on Ventana (Tegra20) and Cardhu (Tegra30).
 This series depends on ccf-rework patch series.
 ---

This series :
Tested-by: Joseph Lo jose...@nvidia.com


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] cpuidle: coupled: abort idle if pokes are pending

2013-08-26 Thread Joseph Lo
On Sat, 2013-08-24 at 03:45 +0800, Colin Cross wrote:
 Joseph Lo jose...@nvidia.com reported a lockup on Tegra3 caused
 by a race condition in coupled cpuidle.  When two or more cpus
Actually this issue can be reproduced on both Tegra20/30 platforms. And
I suggest using Tegra20 to replace Tegra3 here, we only apply coupled
CPU idle function on Tegra20 in the mainline right now.
 enter idle at the same time, the first cpus to arrive may go to the
 ready loop without processing pending pokes from the last cpu to
 arrive.
 
 This patch adds a check for pending pokes once all cpus have been
 synchronized in the ready loop and resets the coupled state and
 retries if any cpus failed to handle their pending poke.
 
 Retrying on all cpus may trigger the same issue again, so this patch
 also adds a check to ensure that each cpu has received at least one
 poke between when it enters the waiting loop and when it moves on to
 the ready loop.
 
 Reported-by: Joseph Lo jose...@nvidia.com
 CC: sta...@vger.kernel.org
 Signed-off-by: Colin Cross ccr...@android.com
 ---
  drivers/cpuidle/coupled.c | 107 
 +++---
  1 file changed, 82 insertions(+), 25 deletions(-)
 
[snip]
 +/*
 + * The cpuidle_coupled_poke_pending mask is used to ensure that each cpu has
s/cpuidle_coupled_poke_pending/cpuidle_coupled_poked/? :)
 + * been poked once to minimize entering the ready loop with a poke pending,
 + * which would require aborting and retrying.
 + */
 +static cpumask_t cpuidle_coupled_poked;
 
I fixed this issue by checking if there is a pending SGI, then abort the
coupled state on Tegra20. It still can be reproduced easily if I remove
the checking code. So I tested the case with this patch, the result is
good. This patch can fix the issue indeed.

I also tested with the other two patches. It didn't cause any
regression.

So this series:
Tested-by: Joseph Lo jose...@nvidia.com


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 06/21] ARM: tegra: call cpu_do_idle from C code

2013-04-23 Thread Joseph Lo
On Wed, 2013-04-24 at 00:30 +0800, Arnd Bergmann wrote:
 When building a kernel for multiple CPU architecture levels,
 cpu_do_idle() is a macro for an indirect function call, which
 cannot be called from assembly code as Tegra does.
 
 Adding a trivial C wrapper for this function lets us build
 a tegra kernel with ARMv6 support enabled.
 
 Signed-off-by: Arnd Bergmann a...@arndb.de
 Cc: Joseph Lo jose...@nvidia.com
 Cc: Stephen Warren swar...@nvidia.com
 ---

Hi Arnd,

Thanks for fixing.

Tested-by: Joseph Lo jose...@nvidia.com

Joseph

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/21] ARM: tegra: unify tegra_idle_device definitions

2013-04-23 Thread Joseph Lo
On Wed, 2013-04-24 at 06:04 +0800, Daniel Lezcano wrote:
 On 04/23/2013 08:57 PM, Arnd Bergmann wrote:
  On Tuesday 23 April 2013, Daniel Lezcano wrote:
  the patch sounds good but I think the side effect of the consolidation
  patchset [1] fixed that.
 
  You can find these fixes in Rafael's tree:
 
  https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-nextamp;id=4c637b2175a0dc65d533494225525c6c82d73293
 
  https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-nextamp;id=e158f9da6974cc11bfab2246a9b10021af0e0d8a
 
  https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-nextamp;id=c5106c9dea9a6022ab84c6cb1d4a0b19fc5af0e2
 
  https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-nextamp;id=f040c26ffaa5e56f2bca427c719c9601a02e70e5
 
  [1] http://www.spinics.net/lists/arm-kernel/msg239811.html
 
  
  Ah. Is that not in linux-next? I created the patch today based on the latest
  linux-next from today (Tuesday).
 
 Ah, ok. Actually the patches were taken by Rafael right today. So it is
 possible the changes were not reflected in linux-next yet.
 
Hi Arnd and Daniel,

Thanks for taking care this.:)

Joseph

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] clk: tegra114: table driven PMC clock init

2013-09-03 Thread Joseph Lo
On Tue, 2013-09-03 at 21:31 +0800, Peter De Schrijver wrote:
 This patch converts the Tegra114 audio clock registration to be table driven
 like the periph clocks.
s/audio/PMC/ :)
 
 Signed-off-by: Peter De Schrijver pdeschrij...@nvidia.com
 ---
  drivers/clk/tegra/clk-tegra114.c |   58 
 +++---
  1 files changed, 23 insertions(+), 35 deletions(-)
 
[snip]


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/32] arm: delete __cpuinit/__CPUINIT usage from all ARM users

2013-07-02 Thread Joseph Lo
Adding linux-tegra in Cc.

On Tue, 2013-06-25 at 03:30 +0800, Paul Gortmaker wrote:
 The __cpuinit type of throwaway sections might have made sense
 some time ago when RAM was more constrained, but now the savings
 do not offset the cost and complications.  For example, the fix in
 commit 5e427ec2d0 (x86: Fix bit corruption at CPU resume time)
 is a good example of the nasty type of bugs that can be created
 with improper use of the various __init prefixes.
 
 After a discussion on LKML[1] it was decided that cpuinit should go
 the way of devinit and be phased out.  Once all the users are gone,
 we can then finally remove the macros themselves from linux/init.h.
 
 Note that some harmless section mismatch warnings may result, since
 notify_cpu_starting() and cpu_up() are arch independent (kernel/cpu.c)
 and are flagged as __cpuinit  -- so if we remove the __cpuinit from
 the arch specific callers, we will also get section mismatch warnings.
 As an intermediate step, we intend to turn the linux/init.h cpuinit
 related content into no-ops as early as possible, since that will get
 rid of these warnings.  In any case, they are temporary and harmless.
 
 This removes all the ARM uses of the __cpuinit macros from C code,
 and all __CPUINIT from assembly code.  It also had two .previous
 section statements that were paired off against __CPUINIT
 (aka .section .cpuinit.text) that also get removed here.
 
 [1] https://lkml.org/lkml/2013/5/20/589
 
 Cc: Russell King li...@arm.linux.org.uk
 Cc: Will Deacon will.dea...@arm.com
 Cc: linux-arm-ker...@lists.infradead.org
 Signed-off-by: Paul Gortmaker paul.gortma...@windriver.com
 ---
 
 [This commit is part of the __cpuinit removal work.  If you don't see
  any problems with it, then you don't have to do anything ; it will be
  submitted with all the rest of the __cpuinit removal work.  On the
  other hand, if you want to carry this patch in with your other pending
  changes so as to handle conflicts with other pending work yourself, then
  that is fine too, as the commits can largely be treated independently.
  For more information, please see: https://lkml.org/lkml/2013/6/20/513 ]
 

Hi Paul,

I just tested this series on Tegra platform. It looks broken CPU hotplug
function for Tegra at least. The CPU can't plug-in after unplugging. And
the system resume function also not working when enable_nonboot_cpus.

Both of the issue cause system hang up. Are we missing something for
__cpuinit removal work?

Thanks,
Joseph

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 04/10] memory: Add Tegra124 memory controller support

2014-06-27 Thread Joseph Lo

Hi Thierry,

On 06/27/2014 04:49 AM, Thierry Reding wrote:
[snip]

+
+#define MC_INTSTATUS 0x000
+#define  MC_INT_DECERR_MTS (1  16)
+#define  MC_INT_SECERR_SEC (1  13)
+#define  MC_INT_DECERR_VPR (1  12)
+#define  MC_INT_INVALID_APB_ASID_UPDATE (1  11)
+#define  MC_INT_INVALID_SMMU_PAGE (1  10)
+#define  MC_INT_ARBITRATION_EMEM (1  9)
+#define  MC_INT_SECURITY_VIOLATION (1  8)
+#define  MC_INT_DECERR_EMEM (1  6)
+#define MC_INTMASK 0x004
+#define MC_ERR_STATUS 0x08
+#define MC_ERR_ADR 0x0c
+

[snip]

+
+#define SMMU_PDE_ATTR  (SMMU_PDE_READABLE | SMMU_PDE_WRITABLE | \
+SMMU_PDE_NONSECURE)
+#define SMMU_PTE_ATTR  (SMMU_PTE_READABLE | SMMU_PTE_WRITABLE | \
+SMMU_PTE_NONSECURE)
+
+#define SMMU_PDE_VACANT(n) (((n)  10) | SMMU_PDE_ATTR)
+#define SMMU_PTE_VACANT(n) (((n)  12) | SMMU_PTE_ATTR)


There is an ISR to catch the invalid SMMU translation. Do you want to 
modify the identity mapping with read/write attribute of the unused SMMU 
pages?


This can make sure we capture the invalid SMMU translation. And helps 
for driver to capture issues when using SMMU.


-joseph


+static irqreturn_t tegra124_mc_irq(int irq, void *data)
+{
+   struct tegra_mc *mc = data;
+   u32 value, status, mask;
+
+   /* mask all interrupts to avoid flooding */
+   mask = mc_readl(mc, MC_INTMASK);
+   mc_writel(mc, 0, MC_INTMASK);
+
+   status = mc_readl(mc, MC_INTSTATUS);
+   mc_writel(mc, status, MC_INTSTATUS);
+
+   dev_dbg(mc-dev, INTSTATUS: %08x\n, status);
+
+   if (status  MC_INT_DECERR_MTS)
+   dev_dbg(mc-dev,   DECERR_MTS\n);
+
+   if (status  MC_INT_SECERR_SEC)
+   dev_dbg(mc-dev,   SECERR_SEC\n);
+
+   if (status  MC_INT_DECERR_VPR)
+   dev_dbg(mc-dev,   DECERR_VPR\n);
+
+   if (status  MC_INT_INVALID_APB_ASID_UPDATE)
+   dev_dbg(mc-dev,   INVALID_APB_ASID_UPDATE\n);
+
+   if (status  MC_INT_INVALID_SMMU_PAGE)
+   dev_dbg(mc-dev,   INVALID_SMMU_PAGE\n);
+
+   if (status  MC_INT_ARBITRATION_EMEM)
+   dev_dbg(mc-dev,   ARBITRATION_EMEM\n);
+
+   if (status  MC_INT_SECURITY_VIOLATION)
+   dev_dbg(mc-dev,   SECURITY_VIOLATION\n);
+
+   if (status  MC_INT_DECERR_EMEM)
+   dev_dbg(mc-dev,   DECERR_EMEM\n);
+
+   value = mc_readl(mc, MC_ERR_STATUS);
+
+   dev_dbg(mc-dev, ERR_STATUS: %08x\n, value);
+   dev_dbg(mc-dev,   type: %x\n, (value  28)  0x7);
+   dev_dbg(mc-dev,   protection: %x\n, (value  25)  0x7);
+   dev_dbg(mc-dev,   adr_hi: %x\n, (value  20)  0x3);
+   dev_dbg(mc-dev,   swap: %x\n, (value  18)  0x1);
+   dev_dbg(mc-dev,   security: %x\n, (value  17)  0x1);
+   dev_dbg(mc-dev,   r/w: %x\n, (value  16)  0x1);
+   dev_dbg(mc-dev,   adr1: %x\n, (value  12)  0x7);
+   dev_dbg(mc-dev,   client: %x\n, value  0x7f);
+
+   value = mc_readl(mc, MC_ERR_ADR);
+   dev_dbg(mc-dev, ERR_ADR: %08x\n, value);
+
+   mc_writel(mc, mask, MC_INTMASK);
+
+   return IRQ_HANDLED;
+}
+

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv4] serial: of-serial: fix up PM ops on no_console_suspend and port type

2014-10-14 Thread Joseph Lo

On 10/14/2014 04:42 PM, Jingchang Lu wrote:

This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
serial: of-serial: add PM suspend/resume support, which disables
the uart clock on suspend, but also causes a hardware hang on register
access if no_console_suspend command line option is used.

Also, not every of_serial device is an 8250 port, so the serial8250
suspend/resume functions should only be applied to a real 8250 port.

Signed-off-by: Jingchang Lu jingchang...@freescale.com


If you can make sure this patch can build without include 
linux/console.h, then this patch


Tested-by: Joseph Lo jose...@nvidia.com

And thanks for your fix.


---
changes in v4:
  separate 8250 port suspend/resume from of_serial_suspend/resume.

changes in v3:
  fix up point reference and deference.

changes in v2:
  add switch selection on uart type.

  drivers/tty/serial/of_serial.c | 52 --
  1 file changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 8bc2563..5281f8f 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -241,13 +241,48 @@ static int of_platform_serial_remove(struct 
platform_device *ofdev)
  }

  #ifdef CONFIG_PM_SLEEP
-static int of_serial_suspend(struct device *dev)
+#ifdef CONFIG_SERIAL_8250
+static void of_serial_suspend_8250(struct of_serial_info *info)
  {
-   struct of_serial_info *info = dev_get_drvdata(dev);
+   struct uart_8250_port *port8250 = serial8250_get_port(info-line);
+   struct uart_port *port = port8250-port;

serial8250_suspend_port(info-line);
-   if (info-clk)
+   if (info-clk  (!uart_console(port) || console_suspend_enabled))
clk_disable_unprepare(info-clk);
+}
+
+static void of_serial_resume_8250(struct of_serial_info *info)
+{
+   struct uart_8250_port *port8250 = serial8250_get_port(info-line);
+   struct uart_port *port = port8250-port;
+
+   if (info-clk  (!uart_console(port) || console_suspend_enabled))
+   clk_prepare_enable(info-clk);
+
+   serial8250_resume_port(info-line);
+}
+#else
+static inline void of_serial_suspend_8250(struct of_serial_info *info)
+{
+}
+
+static inline void of_serial_resume_8250(struct of_serial_info *info)
+{
+}
+#endif
+
+static int of_serial_suspend(struct device *dev)
+{
+   struct of_serial_info *info = dev_get_drvdata(dev);
+
+   switch(info-type) {
+   case PORT_8250 ... PORT_MAX_8250:
+   of_serial_suspend_8250(info);
+   break;
+   default:
+   break;
+   }

return 0;
  }
@@ -256,10 +291,13 @@ static int of_serial_resume(struct device *dev)
  {
struct of_serial_info *info = dev_get_drvdata(dev);

-   if (info-clk)
-   clk_prepare_enable(info-clk);
-
-   serial8250_resume_port(info-line);
+   switch(info-type) {
+   case PORT_8250 ... PORT_MAX_8250:
+   of_serial_resume_8250(info);
+   break;
+   default:
+   break;
+   }

return 0;
  }


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv4] serial: of-serial: fix up PM ops on no_console_suspend and port type

2014-10-15 Thread Joseph Lo

On 10/15/2014 02:32 PM, Jingchang Lu wrote:

-Original Message-
From: Joseph Lo [mailto:jose...@nvidia.com]
Sent: Wednesday, October 15, 2014 9:01 AM
To: Lu Jingchang-B35083; gre...@linuxfoundation.org
Cc: pe...@hurleysoftware.com; a...@arndb.de; linux-kernel@vger.kernel.org;
linux-ser...@vger.kernel.org; linux-arm-ker...@lists.infradead.org
Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
no_console_suspend and port type

On 10/14/2014 04:42 PM, Jingchang Lu wrote:

This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
serial: of-serial: add PM suspend/resume support, which disables the
uart clock on suspend, but also causes a hardware hang on register
access if no_console_suspend command line option is used.

Also, not every of_serial device is an 8250 port, so the serial8250
suspend/resume functions should only be applied to a real 8250 port.

Signed-off-by: Jingchang Lu jingchang...@freescale.com


If you can make sure this patch can build without include
linux/console.h, then this patch

The build passes on my cloned linux-next tree, include next-20141014,
but is required on my another kernel-3.12+ based tree, then I didn't
add this header file when upstream.
Is the build broken on your source tree, and is the tree latest?
If the header is needed, I will add it.
I tested it on next-20141013 and k3.14, both of them need the fix. I can 
check it again against the latest linux-next tree later. Thanks.


-Joseph


Thanks.

Best Regards,
Jingchang


Tested-by: Joseph Lo jose...@nvidia.com

And thanks for your fix.


---
changes in v4:
   separate 8250 port suspend/resume from of_serial_suspend/resume.

changes in v3:
   fix up point reference and deference.

changes in v2:
   add switch selection on uart type.

   drivers/tty/serial/of_serial.c | 52

--

   1 file changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/of_serial.c
b/drivers/tty/serial/of_serial.c index 8bc2563..5281f8f 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -241,13 +241,48 @@ static int of_platform_serial_remove(struct

platform_device *ofdev)

   }

   #ifdef CONFIG_PM_SLEEP
-static int of_serial_suspend(struct device *dev)
+#ifdef CONFIG_SERIAL_8250
+static void of_serial_suspend_8250(struct of_serial_info *info)
   {
-   struct of_serial_info *info = dev_get_drvdata(dev);
+   struct uart_8250_port *port8250 = serial8250_get_port(info-line);
+   struct uart_port *port = port8250-port;

serial8250_suspend_port(info-line);
-   if (info-clk)
+   if (info-clk  (!uart_console(port) || console_suspend_enabled))
clk_disable_unprepare(info-clk);
+}
+
+static void of_serial_resume_8250(struct of_serial_info *info) {
+   struct uart_8250_port *port8250 = serial8250_get_port(info-line);
+   struct uart_port *port = port8250-port;
+
+   if (info-clk  (!uart_console(port) || console_suspend_enabled))
+   clk_prepare_enable(info-clk);
+
+   serial8250_resume_port(info-line);
+}
+#else
+static inline void of_serial_suspend_8250(struct of_serial_info
+*info) { }
+
+static inline void of_serial_resume_8250(struct of_serial_info *info)
+{ } #endif
+
+static int of_serial_suspend(struct device *dev) {
+   struct of_serial_info *info = dev_get_drvdata(dev);
+
+   switch(info-type) {
+   case PORT_8250 ... PORT_MAX_8250:
+   of_serial_suspend_8250(info);
+   break;
+   default:
+   break;
+   }

return 0;
   }
@@ -256,10 +291,13 @@ static int of_serial_resume(struct device *dev)
   {
struct of_serial_info *info = dev_get_drvdata(dev);

-   if (info-clk)
-   clk_prepare_enable(info-clk);
-
-   serial8250_resume_port(info-line);
+   switch(info-type) {
+   case PORT_8250 ... PORT_MAX_8250:
+   of_serial_resume_8250(info);
+   break;
+   default:
+   break;
+   }

return 0;
   }


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv4] serial: of-serial: fix up PM ops on no_console_suspend and port type

2014-10-15 Thread Joseph Lo

On 10/15/2014 02:41 PM, Joseph Lo wrote:

On 10/15/2014 02:32 PM, Jingchang Lu wrote:

-Original Message-
From: Joseph Lo [mailto:jose...@nvidia.com]
Sent: Wednesday, October 15, 2014 9:01 AM
To: Lu Jingchang-B35083; gre...@linuxfoundation.org
Cc: pe...@hurleysoftware.com; a...@arndb.de; linux-kernel@vger.kernel.org;
linux-ser...@vger.kernel.org; linux-arm-ker...@lists.infradead.org
Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
no_console_suspend and port type

On 10/14/2014 04:42 PM, Jingchang Lu wrote:

This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
serial: of-serial: add PM suspend/resume support, which disables the
uart clock on suspend, but also causes a hardware hang on register
access if no_console_suspend command line option is used.

Also, not every of_serial device is an 8250 port, so the serial8250
suspend/resume functions should only be applied to a real 8250 port.

Signed-off-by: Jingchang Lu jingchang...@freescale.com


If you can make sure this patch can build without include
linux/console.h, then this patch

The build passes on my cloned linux-next tree, include next-20141014,
but is required on my another kernel-3.12+ based tree, then I didn't
add this header file when upstream.
Is the build broken on your source tree, and is the tree latest?
If the header is needed, I will add it.

I tested it on next-20141013 and k3.14, both of them need the fix. I can
check it again against the latest linux-next tree later. Thanks.

OK, I confirmed it. You should add the header file. It also doesn't 
build for me with the latest linux-next tree. Maybe you missed to enable 
CONFIG_PM_SLEEP or CONFIG_SERIAL_8250 when doing the build test in 
linux-next tree.


-Joseph
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv5] serial: of-serial: fix up PM ops on no_console_suspend and port type

2014-10-15 Thread Joseph Lo

On 10/15/2014 02:19 PM, Jingchang Lu wrote:

This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
serial: of-serial: add PM suspend/resume support, which disables
the uart clock on suspend, but also causes a hardware hang on register
access if no_console_suspend command line option is used.

Also, not every of_serial device is an 8250 port, so the serial8250
suspend/resume functions should only be applied to a real 8250 port.

Signed-off-by: Jingchang Lu jingchang...@freescale.com
---
changes in v5:
  add missing linux/console.h include.

changes in v4:
  separate 8250 port suspend/resume from of_serial_suspend/resume.

changes in v3:
  fix up point reference and deference.

changes in v2:
  add switch selection on uart type.


Hi Jingchang,

Thanks for the fix. This patch
Tested-by: Joseph Lo jose...@nvidia.com


  drivers/tty/serial/of_serial.c | 53 --
  1 file changed, 46 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 8bc2563..9c64ad2 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -9,6 +9,7 @@
   *  2 of the License, or (at your option) any later version.
   *
   */
+#include linux/console.h
  #include linux/module.h
  #include linux/slab.h
  #include linux/delay.h
@@ -241,13 +242,48 @@ static int of_platform_serial_remove(struct 
platform_device *ofdev)
  }

  #ifdef CONFIG_PM_SLEEP
-static int of_serial_suspend(struct device *dev)
+#ifdef CONFIG_SERIAL_8250
+static void of_serial_suspend_8250(struct of_serial_info *info)
  {
-   struct of_serial_info *info = dev_get_drvdata(dev);
+   struct uart_8250_port *port8250 = serial8250_get_port(info-line);
+   struct uart_port *port = port8250-port;

serial8250_suspend_port(info-line);
-   if (info-clk)
+   if (info-clk  (!uart_console(port) || console_suspend_enabled))
clk_disable_unprepare(info-clk);
+}
+
+static void of_serial_resume_8250(struct of_serial_info *info)
+{
+   struct uart_8250_port *port8250 = serial8250_get_port(info-line);
+   struct uart_port *port = port8250-port;
+
+   if (info-clk  (!uart_console(port) || console_suspend_enabled))
+   clk_prepare_enable(info-clk);
+
+   serial8250_resume_port(info-line);
+}
+#else
+static inline void of_serial_suspend_8250(struct of_serial_info *info)
+{
+}
+
+static inline void of_serial_resume_8250(struct of_serial_info *info)
+{
+}
+#endif
+
+static int of_serial_suspend(struct device *dev)
+{
+   struct of_serial_info *info = dev_get_drvdata(dev);
+
+   switch(info-type) {
+   case PORT_8250 ... PORT_MAX_8250:
+   of_serial_suspend_8250(info);
+   break;
+   default:
+   break;
+   }

return 0;
  }
@@ -256,10 +292,13 @@ static int of_serial_resume(struct device *dev)
  {
struct of_serial_info *info = dev_get_drvdata(dev);

-   if (info-clk)
-   clk_prepare_enable(info-clk);
-
-   serial8250_resume_port(info-line);
+   switch(info-type) {
+   case PORT_8250 ... PORT_MAX_8250:
+   of_serial_resume_8250(info);
+   break;
+   default:
+   break;
+   }

return 0;
  }


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] serial: of-serial: add PM suspend/resume support

2014-10-03 Thread Joseph Lo

Hi,

This patch might have a potential issue that cause system hard hung 
immediately when it accesses to registers with no clock. This could 
happen on many chips that mainline kernel supporting with the setting 
no_console_suspend=1 during suspend time.


On 09/23/2014 04:34 PM, Jingchang Lu wrote:

This adds PM suspend/resume support for the of-serial driver
to provide power management support on devices attatched to it.

Signed-off-by: Jingchang Lu jingchang...@freescale.com
---
  drivers/tty/serial/of_serial.c | 27 +++
  1 file changed, 27 insertions(+)

diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 27981e2..8bc2563 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -240,6 +240,32 @@ static int of_platform_serial_remove(struct 
platform_device *ofdev)
return 0;
  }

+#ifdef CONFIG_PM_SLEEP
+static int of_serial_suspend(struct device *dev)
+{
+   struct of_serial_info *info = dev_get_drvdata(dev);
+
+   serial8250_suspend_port(info-line);
+   if (info-clk)

The fix would be something like this.
if (info-clk  console_suspend_enabled)


+   clk_disable_unprepare(info-clk);
+
+   return 0;
+}
+
+static int of_serial_resume(struct device *dev)
+{
+   struct of_serial_info *info = dev_get_drvdata(dev);
+
+   if (info-clk)

Ditto.

Thanks,
-Joseph

+   clk_prepare_enable(info-clk);
+
+   serial8250_resume_port(info-line);
+
+   return 0;
+}
+#endif
+static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, 
of_serial_resume);
+
  /*
   * A few common types, add more as needed.
   */
@@ -271,6 +297,7 @@ static struct platform_driver of_platform_serial_driver = {
.name = of_serial,
.owner = THIS_MODULE,
.of_match_table = of_platform_serial_table,
+   .pm = of_serial_pm_ops,
},
.probe = of_platform_serial_probe,
.remove = of_platform_serial_remove,


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv2] serial: of-serial: fix up PM ops on no_console_suspend and port type

2014-10-13 Thread Joseph Lo

Hi,

On 10/13/2014 03:37 PM, Jingchang Lu wrote:

This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
serial: of-serial: add PM suspend/resume support, which disables
the uart clock on suspend, but also causes a hardware hang on register
access if no_console_suspend command line option is used.

Also, not every of_serial device is an 8250 port, so the serial8250
suspend/resume functions should only be applied to a real 8250 port.

Signed-off-by: Jingchang Lu jingchang...@freescale.com
---
changes in v2:
  add switch selection on uart type.


After apply this, it can't build for me. I still need to apply the fix 
like something below.


diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index e535f9c1563d..14c1ff4e7816 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -9,6 +9,7 @@
  *  2 of the License, or (at your option) any later version.
  *
  */
+#include linux/console.h
 #include linux/module.h
 #include linux/slab.h
 #include linux/delay.h
@@ -248,13 +249,13 @@ static int of_serial_suspend(struct device *dev)
 #ifdef CONFIG_SERIAL_8250
case PORT_8250 ... PORT_MAX_8250:
{
-   struct uart_8250_port port8250;
+   struct uart_8250_port *port8250;
port8250 = serial8250_get_port(info-line);

serial8250_suspend_port(info-line);
if (info-clk 
-   (!uart_console(port8250) ||
-(uart_console(port8250)  console_suspend_enabled)))
+   (!uart_console(port8250-port) ||
+(uart_console(port8250-port)  
console_suspend_enabled)))

clk_disable_unprepare(info-clk);
break;
}
@@ -274,12 +275,12 @@ static int of_serial_resume(struct device *dev)
 #ifdef CONFIG_SERIAL_8250
case PORT_8250 ... PORT_MAX_8250:
{
-   struct uart_8250_port port8250;
+   struct uart_8250_port *port8250;
port8250 = serial8250_get_port(info-line);

if (info-clk 
-   (!uart_console(port8250) ||
-(uart_console(port8250)  console_suspend_enabled)))
+   (!uart_console(port8250-port) ||
+(uart_console(port8250-port)  
console_suspend_enabled)))

clk_prepare_enable(info-clk);

serial8250_resume_port(info-line);

-Joseph



  drivers/tty/serial/of_serial.c | 42 --
  1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 8bc2563..b525383 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -245,9 +245,24 @@ static int of_serial_suspend(struct device *dev)
  {
struct of_serial_info *info = dev_get_drvdata(dev);

-   serial8250_suspend_port(info-line);
-   if (info-clk)
-   clk_disable_unprepare(info-clk);
+   switch(info-type) {
+#ifdef CONFIG_SERIAL_8250
+   case PORT_8250 ... PORT_MAX_8250:
+   {
+   struct uart_8250_port port8250;
+   port8250 = serial8250_get_port(info-line);
+
+   serial8250_suspend_port(info-line);
+   if (info-clk 
+   (!uart_console(port8250) ||
+(uart_console(port8250)  console_suspend_enabled)))
+   clk_disable_unprepare(info-clk);
+   break;
+   }
+#endif
+   default:
+   break;
+   }

return 0;
  }
@@ -256,10 +271,25 @@ static int of_serial_resume(struct device *dev)
  {
struct of_serial_info *info = dev_get_drvdata(dev);

-   if (info-clk)
-   clk_prepare_enable(info-clk);
+   switch(info-type) {
+#ifdef CONFIG_SERIAL_8250
+   case PORT_8250 ... PORT_MAX_8250:
+   {
+   struct uart_8250_port port8250;
+   port8250 = serial8250_get_port(info-line);
+
+   if (info-clk 
+   (!uart_console(port8250) ||
+(uart_console(port8250)  console_suspend_enabled)))
+   clk_prepare_enable(info-clk);

-   serial8250_resume_port(info-line);
+   serial8250_resume_port(info-line);
+   break;
+   }
+#endif
+   default:
+   break;
+   }

return 0;
  }


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ARM: tegra: Ensure entire dcache is flushed on entering LP0/1

2015-11-21 Thread Joseph Lo

Hi Jon,

On 11/19/2015 10:19 PM, Jon Hunter wrote:

Tegra support several low-power (LPx) states, which are:
- LP0: CPU + Core voltage off and DRAM in self-refresh
- LP1: CPU voltage off and DRAM in self-refresh
- LP2: CPU voltage off

When entering any of the above states the tegra_disable_clean_inv_dcache()
function is called to flush the dcache. The function
tegra_disable_clean_inv_dcache() will either flush the entire data cache or
up to the Level of Unification Inner Shareable (LoUIS) depending on the
value in r0. When tegra_disable_clean_inv_dcache() is called by
tegra20_sleep_core_finish() or tegra30_sleep_core_finish(), to enter LP0
and LP1 power state, the r0 register contains a physical memory address
which will not be equal to TEGRA_FLUSH_CACHE_ALL (1) and so the data cache
will be only flushed to the LoUIS. However, when
tegra_disable_clean_inv_dcache() called by tegra_sleep_cpu_finish() to
enter to LP2 power state, r0 is set to TEGRA_FLUSH_CACHE_ALL to flush the
entire dcache.

Please note that tegra20_sleep_core_finish(), tegra30_sleep_core_finish()
and tegra_sleep_cpu_finish() are called by the boot CPU once all other CPUs
have been disabled and so it seems appropriate to flush the entire cache at
this stage.

Therefore, ensure that r0 is set to TEGRA_FLUSH_CACHE_ALL when calling
tegra_disable_clean_inv_dcache() from tegra20_sleep_core_finish() and
tegra30_sleep_core_finish().

Signed-off-by: Jon Hunter <jonath...@nvidia.com>
---


Thanks for the fix.

Reviewed-by: Joseph Lo <jose...@nvidia.com>



Please note that I have not encountered any problems without this change
so far, but I noticed this from reviewing the suspend sequence. I have
tested this on tegra20, tegra30, tegra114 and tegra124 and verified that
suspend/resume to LP1 is working fine.

  arch/arm/mach-tegra/sleep-tegra20.S | 3 +++
  arch/arm/mach-tegra/sleep-tegra30.S | 3 +++
  2 files changed, 6 insertions(+)

diff --git a/arch/arm/mach-tegra/sleep-tegra20.S 
b/arch/arm/mach-tegra/sleep-tegra20.S
index e6b684e14322..f5d19667484e 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -231,8 +231,11 @@ ENDPROC(tegra20_cpu_is_resettable_soon)
   * tegra20_tear_down_core in IRAM
   */
  ENTRY(tegra20_sleep_core_finish)
+   mov r4, r0
/* Flush, disable the L1 data cache and exit SMP */
+   mov r0, #TEGRA_FLUSH_CACHE_ALL
bl  tegra_disable_clean_inv_dcache
+   mov r0, r4

mov32   r3, tegra_shut_off_mmu
add r3, r3, r0
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S 
b/arch/arm/mach-tegra/sleep-tegra30.S
index 9a2f0b051e10..16e5ff03383c 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -242,8 +242,11 @@ ENDPROC(tegra30_cpu_shutdown)
   * tegra30_tear_down_core in IRAM
   */
  ENTRY(tegra30_sleep_core_finish)
+   mov r4, r0
/* Flush, disable the L1 data cache and exit SMP */
+   mov r0, #TEGRA_FLUSH_CACHE_ALL
bl  tegra_disable_clean_inv_dcache
+   mov r0, r4

/*
 * Preload all the address literals that are needed for the


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-06-28 Thread Joseph Lo

On 06/28/2016 12:08 AM, Stephen Warren wrote:

On 06/27/2016 03:02 AM, Joseph Lo wrote:

The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management tasks
from the CPU. The binding document defines the resources that would be
used by the BPMP firmware driver, which can create the interprocessor
communication (IPC) between the CPU and BPMP.



diff --git
a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt



+The BPMP is a specific processor in Tegra chip, which is designed for
+booting process handling and offloading the power management tasks from
+the CPU. The binding document defines the resources that would be
used by
+the BPMP firmware driver, which can create the interprocessor
+communication (IPC) between the CPU and BPMP.


s/power management/power management, clock management, and reset control/?

Yes.




+Required properties:
+- name : Should be bpmp
+- compatible : Should be "nvidia,tegra-bpmp"


Again, I'd suggest wording this as:

- compatible
 Array of strings.
 One of:
   - "nvidia,tegra186-bpmp"

Okay.



+- mboxes : The phandle of mailbox controller and the channel ID


s/channel ID/mailbox specifier/.


+   See "Documentation/devicetree/bindings/mailbox/
+   nvidia,tegra186-hsp.txt" and "Documentation/devicetree/
+   bindings/mailbox/mailbox.txt" for more details about the generic
+   mailbox controller and mailbox client driver bindings.


I'd rather not split the filenames across lines, since that makes grep
fail to match. Perhaps add the following text to the introductory
section at the start of the file to avoid having to mention some of the
filenames in an indented block of text:

Thanks.


==
This node is a mailbox consumer. See the following file for details of
the mailbox subsystem, and the specifiers implemented by the relevant
provider(s):

- Documentation/devicetree/bindings/mailbox/mailbox.txt
- Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt

This node is a clock and reset provider. See the following files for
general documentation of those features, and the specifiers implemented
by this node:

- Documentation/devicetree/bindings/clock/clock-bindings.txt
- include/dt-bindings/clock/tegra186-clock.h
- Documentation/devicetree/bindings/reset/reset.txt
- include/dt-bindings/reset/tegra186-reset.h
==

Related, I would expect those two header files (tegra186-clock.h and
tegra186-reset.h) to be part of this patch, since they form part of the
definition of this binding.

Okay. Will add them.



+The shared memory bindings for BPMP
+---
+
+The shared memory area for the IPC TX and RX between CPU and BPMP are
+predefined and work on top of sysram, which is a sram inside the chip.


s/a sram/an SRAM/.


+Example:

...

+bpmp@d000 {


There should be no unit address ("@d000") in the node name, since
there's no reg property.


Thanks,
-Joseph


Re: [PATCH 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-06-28 Thread Joseph Lo

On 06/27/2016 11:55 PM, Stephen Warren wrote:

On 06/27/2016 03:02 AM, Joseph Lo wrote:

Add DT binding for the Hardware Synchronization Primitives (HSP). The
HSP is designed for the processors to share resources and communicate
together. It provides a set of hardware synchronization primitives for
interprocessor communication. So the interprocessor communication (IPC)
protocols can use hardware synchronization primitive, when operating
between two processors not in an SMP relationship.


This binding is quite different to the binding you sent to internal IP
review. I wonder why it changed? Specific comments below:

Due to some enhancements for supporting multiple functions of HSP 
sub-modules in the same driver, I re-wrote some parts of the bindings 
and driver.



diff --git
a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt



+NVIDIA Tegra Hardware Synchronization Primitives (HSP)
+
+The HSP modules are used for the processors to share resources and
communicate
+together. It provides a set of hardware synchronization primitives for
+interprocessor communication. So the interprocessor communication (IPC)
+protocols can use hardware synchronization primitives, when operating
between
+two processors not in an SMP relationship.
+
+The features that HSP supported are shared mailboxes, shared semaphores,
+arbitrated semaphores and doorbells.
+
+Required properties:
+- name : Should be hsp
+- compatible : Should be "nvidia,tegra-hsp"


I think this should explicitly list the value values of the compatible
property, rather than being a generic/wildcard description:

- compatible
 Array of strings.
 One of:
   - "nvidia,tegra186-hsp"

If/when this binding supports other SoCs in the future, we'll add more
entries into that list.


+- reg : Offset and length of the register set for the device
+- interrupts : Should contain the HSP interrupts
+- interrupt-names: Should contain the names of the HSP interrupts
that the
+   client are using.
+   "doorbell"


The binding should describe the HW, and not be affected by anything
"that the client(s) are using". If there are multiple interrupts, we
should list them all here, from the start.

When revising this, I would consider the following wording canonical:

Okay.


- interrupt-names
 Array of strings.
 Contains a list of names for the interrupts described by the
 interrupts property. May contain the following entries, in any
 order:
 - "doorbell"
 - "..." (no doubt many more items will be listed here, e.g.
   for semaphores, etc.).
I think I will just list "doorbell" for now. And adding more later once 
we add other HSP sub-module support.



 Users of this binding MUST look up entries in the interrupts
 property by name, using this interrupts-names property to do so.
- interrupts
 Array of interrupt specifiers.
 Must contain one entry per entry in the interrupt-names property,
 in a matching order.


+- nvidia,hsp-function : Specifies one of the HSP functions that the
HSP unit
+will be supported. The function ID can be found in the
+header file .


This property wasn't in the internal patch.

This doesn't make sense. The HW feature-set is fixed. This sounds like
some kind of software configuration option, or a way to allow different
drivers to handle different aspects of the HW? In general, the binding
shouldn't be influenced by software structure. Please delete this property.

Now, if you're attempting to set up a binding where each function
(semaphores, shared mailboxes, doorbells, etc.) has a different DT node,
then (a) splitting up HW modules into sub-blocks has usually turned out
to be a mistake in the past, and (b) the differences should likely be
represented by using a different compatible property for each
sub-component, rather than via a custom property.


Currently the usage of HSP HW in the downstream kernel is something like 
the model below.


remote_processor_A-\
remote_processor_B--->hsp@1000 (doorbell func) <-> host CPU
remote_processor_C-/

remote_processor_D -> hsp@2000 (shared mailbox) <-> CPU

remote_processor_E -> hsp@3000 (shared mailbox) <-> CPU

I am thinking if we can just add the appropriate compatible strings for 
it to replace "nvidia,tegra186-hsp". e.g. "nvidia,tegra186-hsp-doorbell" 
and "nvidia,tegra186-hsp-sharedmailbox". So the driver can probe and 
initialize correctly depend on the compatible property. How do you think 
about it? Is this the same as the (b) you mentioned above?





The following properties were included in the internal patch:

 nvidia,num-SM = <0x8>;
 nvidia,num-AS = <0x2>;
 nvidia,num-SS = <0x2>;
 nvidia,num-DB = <0x7>;

[PATCH V3 3/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-07-19 Thread Joseph Lo
The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management, clock
management, and reset control tasks from the CPU. The binding document
defines the resources that would be used by the BPMP firmware driver,
which can create the interprocessor communication (IPC) between the CPU
and BPMP.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V3:
- s/mmio-ram/mmio-sram/
- revise the file path of the reference binding documents and header files
  for more generic viem in different SW projects
Changes in V2:
- update the message that the BPMP is clock and reset control provider
- add tegra186-clock.h and tegra186-reset.h header files
- revise the description of the required properties
---
 .../bindings/firmware/nvidia,tegra186-bpmp.txt |  77 ++
 include/dt-bindings/clock/tegra186-clock.h | 940 +
 include/dt-bindings/reset/tegra186-reset.h | 217 +
 3 files changed, 1234 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
 create mode 100644 include/dt-bindings/clock/tegra186-clock.h
 create mode 100644 include/dt-bindings/reset/tegra186-reset.h

diff --git 
a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt 
b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
new file mode 100644
index ..23782c84d093
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
@@ -0,0 +1,77 @@
+NVIDIA Tegra Boot and Power Management Processor (BPMP)
+
+The BPMP is a specific processor in Tegra chip, which is designed for
+booting process handling and offloading the power management, clock
+management, and reset control tasks from the CPU. The binding document
+defines the resources that would be used by the BPMP firmware driver,
+which can create the interprocessor communication (IPC) between the CPU
+and BPMP.
+
+Required properties:
+- name : Should be bpmp
+- compatible
+Array of strings
+One of:
+- "nvidia,tegra186-bpmp"
+- mboxes : The phandle of mailbox controller and the mailbox specifier.
+- shmem : List of the phandle of the TX and RX shared memory area that
+ the IPC between CPU and BPMP is based on.
+- #clock-cells : Should be 1.
+- #reset-cells : Should be 1.
+
+This node is a mailbox consumer. See the following files for details of
+the mailbox subsystem, and the specifiers implemented by the relevant
+provider(s):
+
+- .../mailbox/mailbox.txt
+- .../mailbox/nvidia,tegra186-hsp.txt
+
+This node is a clock and reset provider. See the following files for
+general documentation of those features, and the specifiers implemented
+by this node:
+
+- .../clock/clock-bindings.txt
+- 
+- .../reset/reset.txt
+- 
+
+The shared memory bindings for BPMP
+---
+
+The shared memory area for the IPC TX and RX between CPU and BPMP are
+predefined and work on top of sysram, which is an SRAM inside the chip.
+
+See ".../sram/sram.txt" for the bindings.
+
+Example:
+
+hsp_top0: hsp@03c0 {
+   ...
+   #mbox-cells = <2>;
+};
+
+sysram@3000 {
+   compatible = "nvidia,tegra186-sysram", "mmio-sram";
+   reg = <0x0 0x3000 0x0 0x5>;
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges = <0 0x0 0x0 0x3000 0x0 0x5>;
+
+   cpu_bpmp_tx: bpmp_shmem@4e000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4e000 0x0 0x1000>;
+   };
+
+   cpu_bpmp_rx: bpmp_shmem@4f000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4f000 0x0 0x1000>;
+   };
+};
+
+bpmp {
+   compatible = "nvidia,tegra186-bpmp";
+   mboxes = <_top0 HSP_MBOX_TYPE_DB HSP_DB_MASTER_BPMP>;
+   shmem = <_bpmp_tx _bpmp_rx>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+};
diff --git a/include/dt-bindings/clock/tegra186-clock.h 
b/include/dt-bindings/clock/tegra186-clock.h
new file mode 100644
index ..f73d32098f99
--- /dev/null
+++ b/include/dt-bindings/clock/tegra186-clock.h
@@ -0,0 +1,940 @@
+/** @file */
+
+#ifndef _MACH_T186_CLK_T186_H
+#define _MACH_T186_CLK_T186_H
+
+/**
+ * @defgroup clock_ids Clock Identifiers
+ * @{
+ *   @defgroup extern_input external input clocks
+ *   @{
+ * @def TEGRA186_CLK_OSC
+ * @def TEGRA186_CLK_CLK_32K
+ * @def TEGRA186_CLK_DTV_INPUT
+ * @def TEGRA186_CLK_SOR0_PAD_CLKOUT
+ * @def TEGRA186_CLK_SOR1_PAD_CLKOUT
+ * @def TEGRA186_CLK_I2S1_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S2_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S3_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S4_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S5_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S6_SYNC_INPUT
+ * @def TEGRA186_CLK_SPDIFIN_SYNC_INPUT
+ *   

Re: [PATCH V2 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-07-19 Thread Joseph Lo

On 07/19/2016 07:13 AM, Stephen Warren wrote:

On 07/11/2016 10:08 AM, Stephen Warren wrote:

On 07/11/2016 08:14 AM, Rob Herring wrote:

On Thu, Jul 07, 2016 at 12:35:02PM -0600, Stephen Warren wrote:

On 07/07/2016 12:13 PM, Sivaram Nair wrote:

On Tue, Jul 05, 2016 at 05:04:22PM +0800, Joseph Lo wrote:

Add DT binding for the Hardware Synchronization Primitives (HSP). The
HSP is designed for the processors to share resources and communicate
together. It provides a set of hardware synchronization primitives
for
interprocessor communication. So the interprocessor communication
(IPC)
protocols can use hardware synchronization primitive, when operating
between two processors not in an SMP relationship.



diff --git a/include/dt-bindings/mailbox/tegra186-hsp.h
b/include/dt-bindings/mailbox/tegra186-hsp.h



+#define HSP_MBOX_TYPE_DB 0x0
+#define HSP_MBOX_TYPE_SM 0x1
+#define HSP_MBOX_TYPE_SS 0x2
+#define HSP_MBOX_TYPE_AS 0x3
+
+#define HSP_DB_MASTER_CCPLEX 17
+#define HSP_DB_MASTER_BPMP 19
+
+#define HSP_MBOX_ID(type, ID) \
+(HSP_MBOX_TYPE_##type << 16 | ID)


It will be nicer if you avoid the macro glue magic '##' for 'type'. I
would also suggest to use braces around 'type' and 'ID'.


This technique been used without issue in quite a few other places
without
issue, and has the benefit of simplifying the text wherever the
macro is
used. What issue do you foresee?


I'm not a fan of using the macros to begin with and less so anything
more complex than a single constant value. I'd rather see 2 cells here
with the first being the id and the 2nd being the type.

An issue with token pasting is grepping for DB, SM, etc. in kernel tree
is probably noisy. Not such a big deal here, but a major PIA when you
have more complex sets of includes.


Is that a NAK or simply a suggestion? Having a single cell makes DT
parsing a bit simpler, since pretty much every SW stack provides a
default "one-cell" of_xlate implementation, whereas >1 cell means custom
code for of_xlate.


I didn't see a response to this. Joseph, let's just use two cells
instead. I'm rather desperately waiting for this binding to be complete
so I can finalize the U-Boot code that uses it, and it sounds like
changing to two cells will get an ack faster. Can you post an updated
version of this series today/ASAP to get things moving? Thanks.


Okay, will use two cells instead.


[PATCH V3 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-07-19 Thread Joseph Lo
Add DT binding for the Hardware Synchronization Primitives (HSP). The
HSP is designed for the processors to share resources and communicate
together. It provides a set of hardware synchronization primitives for
interprocessor communication. So the interprocessor communication (IPC)
protocols can use hardware synchronization primitive, when operating
between two processors not in an SMP relationship.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Sorry. Please allow me just update the binding patches of this series.
Want to make sure the binding is acceptable first.
Thanks.

Changes in V3:
- use two cells for mboxes property
Changes in V2:
- revise the compatible string, interrupt-names, interrupts, and #mbox-cells
  properties
- remove "nvidia,hsp-function" property
- fix the header file name
- the binding supports the concept of multiple HSP sub-modules on one HSP HW
  block now.
---
 .../bindings/mailbox/nvidia,tegra186-hsp.txt   | 52 ++
 include/dt-bindings/mailbox/tegra186-hsp.h | 20 +
 2 files changed, 72 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
 create mode 100644 include/dt-bindings/mailbox/tegra186-hsp.h

diff --git a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt 
b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
new file mode 100644
index ..a9152380642d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
@@ -0,0 +1,52 @@
+NVIDIA Tegra Hardware Synchronization Primitives (HSP)
+
+The HSP modules are used for the processors to share resources and communicate
+together. It provides a set of hardware synchronization primitives for
+interprocessor communication. So the interprocessor communication (IPC)
+protocols can use hardware synchronization primitives, when operating between
+two processors not in an SMP relationship.
+
+The features that HSP supported are shared mailboxes, shared semaphores,
+arbitrated semaphores and doorbells.
+
+Required properties:
+- name : Should be hsp
+- compatible
+Array of strings.
+one of:
+- "nvidia,tegra186-hsp"
+- reg : Offset and length of the register set for the device.
+- interrupt-names
+Array of strings.
+Contains a list of names for the interrupts described by the interrupt
+property. May contain the following entries, in any order:
+- "doorbell"
+Users of this binding MUST look up entries in the interrupt property
+by name, using this interrupt-names property to do so.
+- interrupts
+Array of interrupt specifiers.
+Must contain one entry per entry in the interrupt-names property,
+in a matching order.
+- #mbox-cells : Should be 2.
+
+The mbox specifier of the "mboxes" property in the client node should
+contain two data. The first one should be the HSP type and the second
+one should be the ID that the client is going to use. Those information
+can be found in the following file.
+
+- .
+
+Example:
+
+hsp_top0: hsp@3c0 {
+   compatible = "nvidia,tegra186-hsp";
+   reg = <0x0 0x03c0 0x0 0xa>;
+   interrupts = ;
+   interrupt-names = "doorbell";
+   #mbox-cells = <2>;
+};
+
+client {
+   ...
+   mboxes = <_top0 HSP_MBOX_TYPE_DB HSP_DB_MASTER_XXX>;
+};
diff --git a/include/dt-bindings/mailbox/tegra186-hsp.h 
b/include/dt-bindings/mailbox/tegra186-hsp.h
new file mode 100644
index ..d1c1432707cd
--- /dev/null
+++ b/include/dt-bindings/mailbox/tegra186-hsp.h
@@ -0,0 +1,20 @@
+/*
+ * This header provides constants for binding nvidia,tegra186-hsp.
+ *
+ * The number with HSP_DB_MASTER prefix indicates the bit that is
+ * associated with a master ID in the doorbell registers.
+ */
+
+
+#ifndef _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H
+#define _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H
+
+#define HSP_MBOX_TYPE_DB 0x0
+#define HSP_MBOX_TYPE_SM 0x1
+#define HSP_MBOX_TYPE_SS 0x2
+#define HSP_MBOX_TYPE_AS 0x3
+
+#define HSP_DB_MASTER_CCPLEX 17
+#define HSP_DB_MASTER_BPMP 19
+
+#endif /* _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H */
-- 
2.9.2



Re: [PATCH V3 3/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-07-19 Thread Joseph Lo

On 07/20/2016 09:22 AM, Rob Herring wrote:

On Tue, Jul 19, 2016 at 05:17:23PM +0800, Joseph Lo wrote:

The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management, clock
management, and reset control tasks from the CPU. The binding document
defines the resources that would be used by the BPMP firmware driver,
which can create the interprocessor communication (IPC) between the CPU
and BPMP.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V3:
- s/mmio-ram/mmio-sram/
- revise the file path of the reference binding documents and header files
  for more generic viem in different SW projects
Changes in V2:
- update the message that the BPMP is clock and reset control provider
- add tegra186-clock.h and tegra186-reset.h header files
- revise the description of the required properties
---
 .../bindings/firmware/nvidia,tegra186-bpmp.txt |  77 ++
 include/dt-bindings/clock/tegra186-clock.h | 940 +
 include/dt-bindings/reset/tegra186-reset.h | 217 +
 3 files changed, 1234 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
 create mode 100644 include/dt-bindings/clock/tegra186-clock.h
 create mode 100644 include/dt-bindings/reset/tegra186-reset.h


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


Rob, Stephen,

Thanks for your review.

-Joseph


Re: [PATCH V2 02/10] mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives) driver

2016-07-18 Thread Joseph Lo

On 07/08/2016 05:10 AM, Sivaram Nair wrote:

On Tue, Jul 05, 2016 at 05:04:23PM +0800, Joseph Lo wrote:

The Tegra HSP mailbox driver implements the signaling doorbell-based
interprocessor communication (IPC) for remote processors currently. The
HSP HW modules support some different features for that, which are
shared mailboxes, shared semaphores, arbitrated semaphores, and
doorbells. And there are multiple HSP HW instances on the chip. So the
driver is extendable to support more features for different IPC
requirement.

The driver of remote processor can use it as a mailbox client and deal
with the IPC protocol to synchronize the data communications.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- Update the driver to support the binding changes in V2
- it's extendable to support multiple HSP sub-modules on the same HSP HW block
   now.
---
  drivers/mailbox/Kconfig |   9 +
  drivers/mailbox/Makefile|   2 +
  drivers/mailbox/tegra-hsp.c | 418 
  3 files changed, 429 insertions(+)
  create mode 100644 drivers/mailbox/tegra-hsp.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 5305923752d2..fe584cb54720 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -114,6 +114,15 @@ config MAILBOX_TEST
  Test client to help with testing new Controller driver
  implementations.

+config TEGRA_HSP_MBOX
+   bool "Tegra HSP(Hardware Synchronization Primitives) Driver"
+   depends on ARCH_TEGRA_186_SOC
+   help
+ The Tegra HSP driver is used for the interprocessor communication
+ between different remote processors and host processors on Tegra186
+ and later SoCs. Say Y here if you want to have this support.
+ If unsure say N.
+
  config XGENE_SLIMPRO_MBOX
tristate "APM SoC X-Gene SLIMpro Mailbox Controller"
depends on ARCH_XGENE
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 0be3e742bb7d..26d8f91c7fea 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -25,3 +25,5 @@ obj-$(CONFIG_TI_MESSAGE_MANAGER) += ti-msgmgr.o
  obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o

  obj-$(CONFIG_HI6220_MBOX) += hi6220-mailbox.o
+
+obj-${CONFIG_TEGRA_HSP_MBOX}   += tegra-hsp.o
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
new file mode 100644
index ..93c3ef58f29f
--- /dev/null
+++ b/drivers/mailbox/tegra-hsp.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HSP_INT_DIMENSIONING   0x380
+#define HSP_nSM_OFFSET 0
+#define HSP_nSS_OFFSET 4
+#define HSP_nAS_OFFSET 8
+#define HSP_nDB_OFFSET 12
+#define HSP_nSI_OFFSET 16
+#define HSP_nINT_MASK  0xf
+
+#define HSP_DB_REG_TRIGGER 0x0
+#define HSP_DB_REG_ENABLE  0x4
+#define HSP_DB_REG_RAW 0x8
+#define HSP_DB_REG_PENDING 0xc
+
+#define HSP_DB_CCPLEX  1
+#define HSP_DB_BPMP3
+
+#define MAX_NUM_HSP_CHAN 32


Is this an arbitrarily chosen number?


Ah, this should be MAX_NUM_HSP_DB_CHAN now.

But the mbox driver still needs a max channel number, I will check how 
to enhance it properly with multiple HSP modules support in the same driver.


Maybe 4 channels for SM, AS, SS and DB. And the sub channels for 
different functions under them. Then it may able to fix the double loop 
issue in the hsp_db_irq function.





+#define MAX_NUM_HSP_DB 7
+
+#define hsp_db_offset(i, d) \
+   (d->base + ((1 + (d->nr_sm >> 1) + d->nr_ss + d->nr_as) << 16) + \
+   (i) * 0x100)
+
+struct tegra_hsp_db_chan {
+   int master_id;
+   int db_id;


These should be unsigned?

Yes, will fix them.




+};
+
+struct tegra_hsp_mbox_chan {
+   int type;


This too...


+   union {
+   struct tegra_hsp_db_chan db_chan;
+   };
+};


Why do we need to use a union?


Because we only support DB right now, there is only one member in the 
union. We can add something like sm_chan here when we need to support 
that later.





+
+struct tegra_hsp_mbox {
+   struct mbox_controller *mbox;
+   void __iomem *base;
+   void __iomem *db_base[MAX_NUM_HSP_DB];
+   int db_irq;
+   int nr_sm;
+   int nr_as;
+   int nr_ss;
+   int nr_db;
+   int nr_si;
+   spinlock_t lock

Re: [PATCH V2 02/10] mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives) driver

2016-07-18 Thread Joseph Lo

On 07/08/2016 05:33 AM, Sivaram Nair wrote:

On Thu, Jul 07, 2016 at 02:37:27PM +0800, Joseph Lo wrote:

On 07/06/2016 08:23 PM, Alexandre Courbot wrote:

On Wed, Jul 6, 2016 at 6:06 PM, Joseph Lo <jose...@nvidia.com> wrote:

On 07/06/2016 03:05 PM, Alexandre Courbot wrote:


On Tue, Jul 5, 2016 at 6:04 PM, Joseph Lo <jose...@nvidia.com> wrote:


The Tegra HSP mailbox driver implements the signaling doorbell-based
interprocessor communication (IPC) for remote processors currently. The
HSP HW modules support some different features for that, which are
shared mailboxes, shared semaphores, arbitrated semaphores, and
doorbells. And there are multiple HSP HW instances on the chip. So the
driver is extendable to support more features for different IPC
requirement.

The driver of remote processor can use it as a mailbox client and deal
with the IPC protocol to synchronize the data communications.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- Update the driver to support the binding changes in V2
- it's extendable to support multiple HSP sub-modules on the same HSP HW
block
now.
---
   drivers/mailbox/Kconfig |   9 +
   drivers/mailbox/Makefile|   2 +
   drivers/mailbox/tegra-hsp.c | 418

   3 files changed, 429 insertions(+)
   create mode 100644 drivers/mailbox/tegra-hsp.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 5305923752d2..fe584cb54720 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -114,6 +114,15 @@ config MAILBOX_TEST
Test client to help with testing new Controller driver
implementations.

+config TEGRA_HSP_MBOX
+   bool "Tegra HSP(Hardware Synchronization Primitives) Driver"



Space missing before the opening parenthesis (same in the patch title
btw).


Okay.




+   depends on ARCH_TEGRA_186_SOC
+   help
+ The Tegra HSP driver is used for the interprocessor
communication
+ between different remote processors and host processors on
Tegra186
+ and later SoCs. Say Y here if you want to have this support.
+ If unsure say N.



Since this option is selected automatically by ARCH_TEGRA_186_SOC, you
should probably drop the last 2 sentences.


Okay.




+
   config XGENE_SLIMPRO_MBOX
  tristate "APM SoC X-Gene SLIMpro Mailbox Controller"
  depends on ARCH_XGENE
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 0be3e742bb7d..26d8f91c7fea 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -25,3 +25,5 @@ obj-$(CONFIG_TI_MESSAGE_MANAGER) += ti-msgmgr.o
   obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o

   obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
+
+obj-${CONFIG_TEGRA_HSP_MBOX}   += tegra-hsp.o
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
new file mode 100644
index ..93c3ef58f29f
--- /dev/null
+++ b/drivers/mailbox/tegra-hsp.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HSP_INT_DIMENSIONING   0x380
+#define HSP_nSM_OFFSET 0
+#define HSP_nSS_OFFSET 4
+#define HSP_nAS_OFFSET 8
+#define HSP_nDB_OFFSET 12
+#define HSP_nSI_OFFSET 16



Would be nice to have comments to understand what SM, SS, AS, etc.
stand for (Shared Mailboxes, Shared Semaphores, Arbitrated Semaphores
but you need to look at the patch description to understand that). A
top-of-file comment explaning the necessary concepts to read this code
would do the trick.


Yes, will fix that.




+#define HSP_nINT_MASK  0xf
+
+#define HSP_DB_REG_TRIGGER 0x0
+#define HSP_DB_REG_ENABLE  0x4
+#define HSP_DB_REG_RAW 0x8
+#define HSP_DB_REG_PENDING 0xc
+
+#define HSP_DB_CCPLEX  1
+#define HSP_DB_BPMP3



Maybe turn this into enum and use that type for
tegra_hsp_db_chan::db_id? Also have MAX_NUM_HSP_DB here, since it is
related to these values?


Okay.




+
+#define MAX_NUM_HSP_CHAN 32
+#define MAX_NUM_HSP_DB 7
+
+#define hsp_db_offset(i, d) \
+   (d->base + ((1 + (d->nr_sm >> 1) + d->nr_ss + d->nr_as) << 16) +
\
+   (i) * 0x100)
+
+struct tegra_hsp_db_chan {
+   int master_id;
+   int db_id;
+};
+
+struct tegra_hsp_mbox_chan {
+   int type;
+   union {
+   struct tegra_hsp_db_chan db_

Re: [PATCH V2 03/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-07-18 Thread Joseph Lo

Hi Rob,

Thanks for your reviewing.

On 07/12/2016 12:05 AM, Stephen Warren wrote:

On 07/11/2016 08:22 AM, Rob Herring wrote:

On Tue, Jul 05, 2016 at 05:04:24PM +0800, Joseph Lo wrote:

The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management, clock
management, and reset control tasks from the CPU. The binding document
defines the resources that would be used by the BPMP firmware driver,
which can create the interprocessor communication (IPC) between the CPU
and BPMP.



diff --git
a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt



+NVIDIA Tegra Boot and Power Management Processor (BPMP)
+
+The BPMP is a specific processor in Tegra chip, which is designed for
+booting process handling and offloading the power management, clock
+management, and reset control tasks from the CPU. The binding document
+defines the resources that would be used by the BPMP firmware driver,
+which can create the interprocessor communication (IPC) between the CPU
+and BPMP.
+
+Required properties:
+- name : Should be bpmp
+- compatible
+Array of strings
+One of:
+- "nvidia,tegra186-bpmp"
+- mboxes : The phandle of mailbox controller and the mailbox specifier.
+- shmem : List of the phandle of the TX and RX shared memory area that
+  the IPC between CPU and BPMP is based on.


I think you can use memory-region here.


Isn't memory-region intended for references into the /reserved-memory
node. If so, that isn't appropriate in this case since this property
typically points at on-chip SRAM that isn't included in the OS's view of
"system RAM".

Agree with that.



Or, should /reserved-memory be used even for (e.g. non-DRAM) memory
regions that aren't represented by the /memory/reg property?



For shmem, I follow the same concept of the binding for arm,scpi 
(.../arm/arm,scpi.txt) that is currently using in mainline. Do you think 
that is more appropriate here?




diff --git a/include/dt-bindings/clock/tegra186-clock.h
b/include/dt-bindings/clock/tegra186-clock.h



+/** @file */
+
+#ifndef _MACH_T186_CLK_T186_H
+#define _MACH_T186_CLK_T186_H
+
+/**
+ * @defgroup clock_ids Clock Identifiers


Aren't these doxygen markup? Does that work with docbook? If not,
remove.


These headers are part of the BPMP FW release. It's preferable not to
edit them when incorporating them into the Linux kernel (or any other SW
stack) to simplify integration of any updated versions of the header, by
removing the need to edit the file when doing so. Given that, do you
still object?


How do you think of this, Rob?

Thanks,
-Joseph


Re: [PATCH V2 03/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-07-18 Thread Joseph Lo

On 07/14/2016 03:41 AM, Stephen Warren wrote:

On 07/05/2016 03:04 AM, Joseph Lo wrote:

The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management, clock
management, and reset control tasks from the CPU. The binding document
defines the resources that would be used by the BPMP firmware driver,
which can create the interprocessor communication (IPC) between the CPU
and BPMP.



diff --git
a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt



+- Documentation/devicetree/bindings/mailbox/mailbox.txt
+- Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt



+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+- include/dt-bindings/clock/tegra186-clock.h
+- Documentation/devicetree/bindings/reset/reset.txt
+- include/dt-bindings/reset/tegra186-reset.h


If you end up needing to repost this, it would be nice to make all those
file references more generic. In particular, some SW projects store
binding docs somewhere other than Documentation/devicetree/bindings/
(e.g. U-Boot uses doc/device-tree-bindings/), and it's possible that the
header files aren't stored in include/ but somewhere else. To make these
file references valid everywhere, I'd suggest using relative paths for
the binding docs, and #include style paths for the headers, e.g.:

../clock/clock-bindings.txt




OK. Will fix this.

Thanks,
-Joseph


[PATCH 05/10] firmware: tegra: add BPMP support

2016-06-27 Thread Joseph Lo
The Tegra BPMP (Boot and Power Management Processor) is designed for the
booting process handling, offloading the power management tasks and
some system control services from the CPU. It can be clock, DVFS,
thermal/EDP, power gating operation and system suspend/resume handling.
So the CPU and the drivers of these modules can base on the service that
the BPMP firmware driver provided to signal the event for the specific PM
action to BPMP and receive the status update from BPMP.

Comparing to the ARM SCPI, the service provided by BPMP is message-based
communication but not method-based. The BPMP firmware driver provides the
send/receive service for the users, when the user concerns the response
time. If the user needs to get the event or update from the firmware, it
can request the MRQ service as well. The user needs to take care of the
message format, which we call BPMP ABI.

The BPMP ABI defines the message format for different modules or usages.
For example, the clock operation needs an MRQ service code called
MRQ_CLK with specific message format which includes different sub
commands for various clock operations. This is the message format that
BPMP can recognize.

So the user needs two things to initiate IPC between BPMP. Get the
service from the bpmp_ops structure and maintain the message format as
the BPMP ABI defined.

Based-on-the-work-by:
Sivaram Nair <sivar...@nvidia.com>

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 drivers/firmware/tegra/Kconfig  |   12 +
 drivers/firmware/tegra/Makefile |1 +
 drivers/firmware/tegra/bpmp.c   |  713 +
 include/soc/tegra/bpmp.h|   29 +
 include/soc/tegra/bpmp_abi.h| 1601 +++
 5 files changed, 2356 insertions(+)
 create mode 100644 drivers/firmware/tegra/bpmp.c
 create mode 100644 include/soc/tegra/bpmp.h
 create mode 100644 include/soc/tegra/bpmp_abi.h

diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig
index 1fa3e4e136a5..ff2730d5c468 100644
--- a/drivers/firmware/tegra/Kconfig
+++ b/drivers/firmware/tegra/Kconfig
@@ -10,4 +10,16 @@ config TEGRA_IVC
  keeps the content is synchronization between host CPU and remote
  processors.
 
+config TEGRA_BPMP
+   bool "Tegra BPMP driver"
+   depends on ARCH_TEGRA && TEGRA_HSP_MBOX && TEGRA_IVC
+   help
+ BPMP (Boot and Power Management Processor) is designed to off-loading
+ the PM functions which include clock/DVFS/thermal/power from the CPU.
+ It needs HSP as the HW synchronization and notification module and
+ IVC module as the message communication protocol.
+
+ This driver manages the IPC interface between host CPU and the
+ firmware running on BPMP.
+
 endmenu
diff --git a/drivers/firmware/tegra/Makefile b/drivers/firmware/tegra/Makefile
index 92e2153e8173..e34a2f79e1ad 100644
--- a/drivers/firmware/tegra/Makefile
+++ b/drivers/firmware/tegra/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_TEGRA_BPMP)   += bpmp.o
 obj-$(CONFIG_TEGRA_IVC)+= ivc.o
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
new file mode 100644
index ..24fda626610e
--- /dev/null
+++ b/drivers/firmware/tegra/bpmp.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define BPMP_MSG_SZ128
+#define BPMP_MSG_DATA_SZ   120
+
+#define __MRQ_ATTRS0xff00
+#define __MRQ_INDEX(id)((id) & ~__MRQ_ATTRS)
+
+#define DO_ACK BIT(0)
+#define RING_DOORBELL  BIT(1)
+
+struct tegra_bpmp_soc_data {
+   u32 ch_index;   /* channel index */
+   u32 thread_ch_index;/* thread channel index */
+   u32 cpu_rx_ch_index;/* CPU Rx channel index */
+   u32 nr_ch;  /* number of total channels */
+   u32 nr_thread_ch;   /* number of thread channels */
+   u32 ch_timeout; /* channel timeout */
+   u32 thread_ch_timeout;  /* thread channel timeout */
+};
+
+struct channel_info {
+   u32 tch_free;
+   u32 tch_to_complete;
+   struct semaphore tch_sem;
+};
+
+struct mb_data {
+   s32 code;
+   s32 flags;
+   u8 data[BPMP_MSG_DATA_SZ];
+} __packed;
+
+struct channel_data {
+   struct mb_data *ib;
+   struct mb_data *ob;
+};
+
+struct mrq {
+   s

[PATCH 06/10] soc/tegra: Add Tegra186 support

2016-06-27 Thread Joseph Lo
The Tegra186 has a combination of Denver and Cortex-A57 CPU cores and
GPUs with Pascal architecture on it. It features with ADSP with
Cortex-A9 CPU for audio processing, hardware video encoder/decoder with
multi-format support, ISP for image capture processing and BPMP for the
power managements.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 drivers/soc/tegra/Kconfig | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 03089ad2fc65..88a71dfd466c 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -61,6 +61,20 @@ config ARCH_TEGRA_132_SOC
  but contains an NVIDIA Denver CPU complex in place of
  Tegra124's "4+1" Cortex-A15 CPU complex.
 
+config ARCH_TEGRA_186_SOC
+   bool "NVIDIA Tegra186 SoC"
+   select MAILBOX
+   select TEGRA_BPMP
+   select TEGRA_HSP_MBOX
+   select TEGRA_IVC
+   help
+ Enable support for the NVIDIA Tegar186 SoC. The Tegra186 has a
+ combination of Denver and Cortex-A57 CPU cores and GPUs with Pascal
+ architecture on it. It features with ADSP with Cortex-A9 CPU for
+ audio processing, hardware video encoder/decoder with multi-format
+ support, ISP for image capture processing and BPMP for the power
+ managements.
+
 config ARCH_TEGRA_210_SOC
bool "NVIDIA Tegra210 SoC"
select PINCTRL_TEGRA210
-- 
2.9.0



[PATCH 04/10] firmware: tegra: add IVC library

2016-06-27 Thread Joseph Lo
The Inter-VM communication (IVC) is a communication protocol, which is
designed for interprocessor communication (IPC) or the communication
between the hypervisor and the virtual machine with a guest OS on it. So
it can be translated as inter-virtual memory or inter-virtual machine
communication. The message channels are maintained on the DRAM or SRAM
and the data coherency should be considered. Or the data could be
corrupted or out of date when the remote client checking it.

Inside the IVC, it maintains memory-based descriptors for the TX/RX
channels and the coherency issue of the counter and payloads. So the
clients can use it to send/receive messages to/from remote ones.

We introduce it as a library for the firmware drivers, which can use it
for IPC.

Based-on-the-work-by:
Peter Newman <pnew...@nvidia.com>

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 drivers/firmware/Kconfig|   1 +
 drivers/firmware/Makefile   |   1 +
 drivers/firmware/tegra/Kconfig  |  13 +
 drivers/firmware/tegra/Makefile |   1 +
 drivers/firmware/tegra/ivc.c| 659 
 include/soc/tegra/ivc.h | 102 +++
 6 files changed, 777 insertions(+)
 create mode 100644 drivers/firmware/tegra/Kconfig
 create mode 100644 drivers/firmware/tegra/Makefile
 create mode 100644 drivers/firmware/tegra/ivc.c
 create mode 100644 include/soc/tegra/ivc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 6664f1108c7c..8602d81a6072 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -199,5 +199,6 @@ config HAVE_ARM_SMCCC
 source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
+source "drivers/firmware/tegra/Kconfig"
 
 endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 474bada56fcd..9a4df8171cc4 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -24,3 +24,4 @@ obj-y += broadcom/
 obj-$(CONFIG_GOOGLE_FIRMWARE)  += google/
 obj-$(CONFIG_EFI)  += efi/
 obj-$(CONFIG_UEFI_CPER)+= efi/
+obj-y  += tegra/
diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig
new file mode 100644
index ..1fa3e4e136a5
--- /dev/null
+++ b/drivers/firmware/tegra/Kconfig
@@ -0,0 +1,13 @@
+menu "Tegra firmware driver"
+
+config TEGRA_IVC
+   bool "Tegra IVC protocol"
+   depends on ARCH_TEGRA
+   help
+ IVC (Inter-VM Communication) protocol is part of the IPC
+ (Inter Processor Communication) framework on Tegra. It maintains the
+ data and the different commuication channels in SysRAM or RAM and
+ keeps the content is synchronization between host CPU and remote
+ processors.
+
+endmenu
diff --git a/drivers/firmware/tegra/Makefile b/drivers/firmware/tegra/Makefile
new file mode 100644
index ..92e2153e8173
--- /dev/null
+++ b/drivers/firmware/tegra/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TEGRA_IVC)+= ivc.o
diff --git a/drivers/firmware/tegra/ivc.c b/drivers/firmware/tegra/ivc.c
new file mode 100644
index ..3e736bb9915a
--- /dev/null
+++ b/drivers/firmware/tegra/ivc.c
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+
+#include 
+
+#define IVC_ALIGN 64
+
+#ifdef CONFIG_SMP
+
+static inline void ivc_rmb(void)
+{
+   smp_rmb();
+}
+
+static inline void ivc_wmb(void)
+{
+   smp_wmb();
+}
+
+static inline void ivc_mb(void)
+{
+   smp_mb();
+}
+
+#else
+
+static inline void ivc_rmb(void)
+{
+   rmb();
+}
+
+static inline void ivc_wmb(void)
+{
+   wmb();
+}
+
+static inline void ivc_mb(void)
+{
+   mb();
+}
+
+#endif
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum ivc_state {
+   /*
+* This value is zero for backwards compatibility with services that
+* assume channels to be initially zeroed. Such channels are in an
+* initially valid state, but cannot be asynchronously reset, and must
+* maintain a valid state at all times.
+*
+* The transmitting end can enter the established state from the sync or
+* ack state when it observes the receiving endpoint in the ack or
+* established stat

[PATCH 02/10] mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives) driver

2016-06-27 Thread Joseph Lo
The Tegra HSP mailbox driver implements the signaling doorbell-based
interprocessor communication (IPC) for remote processors currently. The
HSP HW modules support some different features for that, which are
shared mailboxes, shared semaphores, arbitrated semaphores, and
doorbells. And there are multiple HSP HW instances on the chip. So the
driver is extendable to support more features for different IPC
requirement.

The driver of remote processor can use it as a mailbox client and deal
with the IPC protocol to synchronize the data communications.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 drivers/mailbox/Kconfig |   9 ++
 drivers/mailbox/Makefile|   2 +
 drivers/mailbox/tegra-hsp.c | 306 
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/mailbox/tegra-hsp.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 5305923752d2..fe584cb54720 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -114,6 +114,15 @@ config MAILBOX_TEST
  Test client to help with testing new Controller driver
  implementations.
 
+config TEGRA_HSP_MBOX
+   bool "Tegra HSP(Hardware Synchronization Primitives) Driver"
+   depends on ARCH_TEGRA_186_SOC
+   help
+ The Tegra HSP driver is used for the interprocessor communication
+ between different remote processors and host processors on Tegra186
+ and later SoCs. Say Y here if you want to have this support.
+ If unsure say N.
+
 config XGENE_SLIMPRO_MBOX
tristate "APM SoC X-Gene SLIMpro Mailbox Controller"
depends on ARCH_XGENE
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 0be3e742bb7d..26d8f91c7fea 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -25,3 +25,5 @@ obj-$(CONFIG_TI_MESSAGE_MANAGER) += ti-msgmgr.o
 obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o
 
 obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
+
+obj-${CONFIG_TEGRA_HSP_MBOX}   += tegra-hsp.o
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
new file mode 100644
index ..85bf5372681d
--- /dev/null
+++ b/drivers/mailbox/tegra-hsp.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HSP_INT_DIMENSIONING   0x380
+#define HSP_nSM_OFFSET 0
+#define HSP_nSS_OFFSET 4
+#define HSP_nAS_OFFSET 8
+#define HSP_nDB_OFFSET 12
+#define HSP_nSI_OFFSET 16
+#define HSP_nINT_MASK  0xf
+
+#define HSP_DB_REG_TRIGGER 0x0
+#define HSP_DB_REG_ENABLE  0x4
+#define HSP_DB_REG_RAW 0x8
+#define HSP_DB_REG_PENDING 0xc
+
+#define HSP_DB_CCPLEX  1
+#define HSP_DB_BPMP3
+
+#define MAX_NUM_HSP_CHAN 32
+#define MAX_NUM_HSP_DB 7
+
+#define hsp_db_offset(i, d) \
+   (d->base + ((1 + (d->nr_sm >> 1) + d->nr_ss + d->nr_as) << 16) + \
+   (i) * 0x100)
+
+struct tegra_hsp_db_chan {
+   int master_id;
+   int db_id;
+};
+
+struct tegra_hsp_mbox {
+   struct mbox_controller *db_mbox;
+   void __iomem *base;
+   void __iomem *db_base[MAX_NUM_HSP_DB];
+   int nr_sm;
+   int nr_as;
+   int nr_ss;
+   int nr_db;
+   int nr_si;
+   spinlock_t lock;
+};
+
+static inline u32 hsp_readl(void __iomem *base, int reg)
+{
+   return readl(base + reg);
+}
+
+static inline void hsp_writel(void __iomem *base, int reg, u32 val)
+{
+   writel(val, base + reg);
+   readl(base + reg);
+}
+
+static int hsp_db_can_ring(void __iomem *db_base)
+{
+   u32 reg;
+
+   reg = hsp_readl(db_base, HSP_DB_REG_ENABLE);
+
+   return !!(reg & BIT(HSP_DB_MASTER_CCPLEX));
+}
+
+static irqreturn_t hsp_db_irq(int irq, void *p)
+{
+   struct tegra_hsp_mbox *hsp_mbox = p;
+   ulong val;
+   int master_id;
+
+   val = (ulong)hsp_readl(hsp_mbox->db_base[HSP_DB_CCPLEX],
+  HSP_DB_REG_PENDING);
+   hsp_writel(hsp_mbox->db_base[HSP_DB_CCPLEX], HSP_DB_REG_PENDING, val);
+
+   spin_lock(_mbox->lock);
+   for_each_set_bit(master_id, , MAX_NUM_HSP_CHAN) {
+   struct mbox_chan *chan = _mbox->db_mbox->chans[master_id];
+   struct tegra_hsp_db_chan *db_chan = chan->con_priv;
+
+   if (master_id == db_chan->master_id)
+   mbo

[PATCH 00/10] arm64: tegra: add BPMP support

2016-06-27 Thread Joseph Lo
Hi,

This series introduce the first announced Boot and Power Management Processor
(BPMP) for the new generation Tegra SoCs, which is designed for boot
process handling and offloading the power management tasks from the CPU.

We also add some very initial and basic support for Tegra186 SoC, which
supports debug console and initrd for initial bring up currently. More drivers
and functions can be supported based on this later.

Thanks,
Joseph

Joseph Lo (10):
  Documentation: dt-bindings: mailbox: tegra: Add binding for HSP
mailbox
  mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives)
driver
  Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP
  firmware: tegra: add IVC library
  firmware: tegra: add BPMP support
  soc/tegra: Add Tegra186 support
  arm64: defconfig: Enable Tegra186 SoC
  arm64: dts: tegra: Add Tegra186 support
  arm64: dts: tegra: Add NVIDIA Tegra186 P3310 main board support
  arm64: dts: tegra: Add NVIDIA P2771 board support

 .../bindings/firmware/nvidia,tegra186-bpmp.txt |   61 +
 .../bindings/mailbox/nvidia,tegra186-hsp.txt   |   42 +
 arch/arm64/boot/dts/nvidia/Makefile|1 +
 arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts |8 +
 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi |   30 +
 arch/arm64/boot/dts/nvidia/tegra186.dtsi   |   77 +
 arch/arm64/configs/defconfig   |1 +
 drivers/firmware/Kconfig   |1 +
 drivers/firmware/Makefile  |1 +
 drivers/firmware/tegra/Kconfig |   25 +
 drivers/firmware/tegra/Makefile|2 +
 drivers/firmware/tegra/bpmp.c  |  713 +
 drivers/firmware/tegra/ivc.c   |  659 
 drivers/mailbox/Kconfig|9 +
 drivers/mailbox/Makefile   |2 +
 drivers/mailbox/tegra-hsp.c|  306 
 drivers/soc/tegra/Kconfig  |   14 +
 include/dt-bindings/mailbox/tegra-hsp.h|   20 +
 include/soc/tegra/bpmp.h   |   29 +
 include/soc/tegra/bpmp_abi.h   | 1601 
 include/soc/tegra/ivc.h|  102 ++
 21 files changed, 3704 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
 create mode 100644 
Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186.dtsi
 create mode 100644 drivers/firmware/tegra/Kconfig
 create mode 100644 drivers/firmware/tegra/Makefile
 create mode 100644 drivers/firmware/tegra/bpmp.c
 create mode 100644 drivers/firmware/tegra/ivc.c
 create mode 100644 drivers/mailbox/tegra-hsp.c
 create mode 100644 include/dt-bindings/mailbox/tegra-hsp.h
 create mode 100644 include/soc/tegra/bpmp.h
 create mode 100644 include/soc/tegra/bpmp_abi.h
 create mode 100644 include/soc/tegra/ivc.h

-- 
2.9.0



[PATCH 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-06-27 Thread Joseph Lo
Add DT binding for the Hardware Synchronization Primitives (HSP). The
HSP is designed for the processors to share resources and communicate
together. It provides a set of hardware synchronization primitives for
interprocessor communication. So the interprocessor communication (IPC)
protocols can use hardware synchronization primitive, when operating
between two processors not in an SMP relationship.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 .../bindings/mailbox/nvidia,tegra186-hsp.txt   | 42 ++
 include/dt-bindings/mailbox/tegra-hsp.h| 20 +++
 2 files changed, 62 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
 create mode 100644 include/dt-bindings/mailbox/tegra-hsp.h

diff --git a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt 
b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
new file mode 100644
index ..ca07af2d951e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
@@ -0,0 +1,42 @@
+NVIDIA Tegra Hardware Synchronization Primitives (HSP)
+
+The HSP modules are used for the processors to share resources and communicate
+together. It provides a set of hardware synchronization primitives for
+interprocessor communication. So the interprocessor communication (IPC)
+protocols can use hardware synchronization primitives, when operating between
+two processors not in an SMP relationship.
+
+The features that HSP supported are shared mailboxes, shared semaphores,
+arbitrated semaphores and doorbells.
+
+Required properties:
+- name : Should be hsp
+- compatible : Should be "nvidia,tegra-hsp"
+- reg : Offset and length of the register set for the device
+- interrupts : Should contain the HSP interrupts
+- interrupt-names: Should contain the names of the HSP interrupts that the
+  client are using.
+  "doorbell"
+- nvidia,hsp-function : Specifies one of the HSP functions that the HSP unit
+   will be supported. The function ID can be found in the
+   header file .
+- #mbox-cells : Should be 1. Specifies the HSP master that will be enabled of
+   the HSP client. The master ID constants can be found in the
+   header file .
+
+Example:
+
+hsp_top: hsp@3c0 {
+   compatible = "nvidia,tegra186-hsp";
+   reg = <0x0 0x03c0 0x0 0xa>;
+   interrupts = ;
+   interrupt-names = "doorbell";
+   nvidia,hsp-function = ;
+   #mbox-cells = <1>;
+};
+
+bpmp@d000 {
+   ...
+   mboxes = <_top HSP_DB_MASTER_BPMP>;
+   ...
+};
diff --git a/include/dt-bindings/mailbox/tegra-hsp.h 
b/include/dt-bindings/mailbox/tegra-hsp.h
new file mode 100644
index ..720c66784b72
--- /dev/null
+++ b/include/dt-bindings/mailbox/tegra-hsp.h
@@ -0,0 +1,20 @@
+/*
+ * This header provides constants for binding nvidia,tegra-hsp.
+ *
+ * The number with HSP_DB_MASTER prefix indicates the bit that is
+ * associated with a master ID in the doorbell registers.
+ */
+
+
+#ifndef _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H
+#define _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H
+
+#define HSP_SHARED_MAILBOX 0
+#define HSP_SHARED_SEMAPHORE   1
+#define HSP_ARBITRATED_SEMAPHORE   2
+#define HSP_DOORBELL   3
+
+#define HSP_DB_MASTER_CCPLEX 17
+#define HSP_DB_MASTER_BPMP 19
+
+#endif /* _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H */
-- 
2.9.0



[PATCH 03/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-06-27 Thread Joseph Lo
The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management tasks
from the CPU. The binding document defines the resources that would be
used by the BPMP firmware driver, which can create the interprocessor
communication (IPC) between the CPU and BPMP.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 .../bindings/firmware/nvidia,tegra186-bpmp.txt | 61 ++
 1 file changed, 61 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt

diff --git 
a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt 
b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
new file mode 100644
index ..34a252d87e17
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
@@ -0,0 +1,61 @@
+NVIDIA Tegra Boot and Power Management Processor (BPMP)
+
+The BPMP is a specific processor in Tegra chip, which is designed for
+booting process handling and offloading the power management tasks from
+the CPU. The binding document defines the resources that would be used by
+the BPMP firmware driver, which can create the interprocessor
+communication (IPC) between the CPU and BPMP.
+
+Required properties:
+- name : Should be bpmp
+- compatible : Should be "nvidia,tegra-bpmp"
+- mboxes : The phandle of mailbox controller and the channel ID
+   See "Documentation/devicetree/bindings/mailbox/
+  nvidia,tegra186-hsp.txt" and "Documentation/devicetree/
+  bindings/mailbox/mailbox.txt" for more details about the generic
+  mailbox controller and mailbox client driver bindings.
+- shmem : List of the phandle of the TX and RX shared memory area that
+ the IPC between CPU and BPMP is based on.
+- #clock-cells : Should be 1.
+- #reset-cells : Should be 1.
+
+The shared memory bindings for BPMP
+---
+
+The shared memory area for the IPC TX and RX between CPU and BPMP are
+predefined and work on top of sysram, which is a sram inside the chip.
+
+See "Documentation/devicetree/bindings/sram/sram.txt" for the bindings.
+
+Example:
+
+hsp_top: hsp@03c0 {
+   ...
+   #mbox-cells = <1>;
+};
+
+bpmp@d000 {
+   compatible = "nvidia,tegra186-bpmp";
+   mboxes = <_mbox HSP_DB_MASTER_BPMP>;
+   shmem = <_bpmp_tx _bpmp_rx>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+};
+
+sysram@3000 {
+   compatible = "nvidia,tegra186-sysram", "mmio-ram";
+   reg = <0x0 0x3000 0x0 0x5>;
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges = <0 0x0 0x0 0x3000 0x0 0x5>;
+
+   cpu_bpmp_tx: bpmp_shmem@4e000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4e000 0x0 0x1000>;
+   };
+
+   cpu_bpmp_rx: bpmp_shmem@4f000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4f000 0x0 0x1000>;
+   };
+};
-- 
2.9.0



[PATCH 10/10] arm64: dts: tegra: Add NVIDIA P2771 board support

2016-06-27 Thread Joseph Lo
Add NVIDIA Tegra186 P2771 board support, which is a reference
development board with P2597 I/O board and P3310 chip module on it.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/Makefile| 1 +
 arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts | 8 
 2 files changed, 9 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts

diff --git a/arch/arm64/boot/dts/nvidia/Makefile 
b/arch/arm64/boot/dts/nvidia/Makefile
index 0f7cdf3e05c1..67234f3dc795 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -1,4 +1,5 @@
 dtb-$(CONFIG_ARCH_TEGRA_132_SOC) += tegra132-norrin.dtb
+dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts 
b/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts
new file mode 100644
index ..66b936389fa7
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "tegra186-p3310.dtsi"
+
+/ {
+   model = "NVIDIA Tegra186 P2771- Board";
+   compatible = "nvidia,p2771-", "nvidia,tegra186";
+};
-- 
2.9.0



[PATCH 08/10] arm64: dts: tegra: Add Tegra186 support

2016-06-27 Thread Joseph Lo
This adds the initial support of Tegra186 SoC, which can help to bring
up the debug console and initrd for further developing.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 77 
 1 file changed, 77 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186.dtsi

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
new file mode 100644
index ..bed30f30bb0b
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -0,0 +1,77 @@
+#include 
+#include 
+
+/ {
+   compatible = "nvidia,tegra186";
+   interrupt-parent = <>;
+   #address-cells = <2>;
+   #size-cells = <2>;
+
+   uarta: serial@0310 {
+   compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+   reg = <0x0 0x0310 0x0 0x40>;
+   reg-shift = <2>;
+   interrupts = ;
+   status = "disabled";
+   };
+
+   gic: interrupt-controller@03881000 {
+   compatible = "arm,gic-400";
+   #interrupt-cells = <3>;
+   interrupt-controller;
+   reg = <0x0 0x03881000 0x0 0x1000>,
+ <0x0 0x03882000 0x0 0x2000>;
+   interrupts = ;
+   interrupt-parent = <>;
+   };
+
+   hsp_top: hsp@03c0 {
+   compatible = "nvidia,tegra186-hsp";
+   reg = <0x0 0x03c0 0x0 0xa>;
+   interrupts = ;
+   interrupt-names = "doorbell";
+   nvidia,hsp-function = ;
+   #mbox-cells = <1>;
+   };
+
+   bpmp@d000 {
+   compatible = "nvidia,tegra186-bpmp";
+   mboxes = <_top HSP_DB_MASTER_BPMP>;
+   shmem = <_bpmp_tx _bpmp_rx>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   status = "disabled";
+   };
+
+   sysram@3000 {
+   compatible = "nvidia,tegra186-sysram", "mmio-ram";
+   reg = <0x0 0x3000 0x0 0x4>;
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges = <0 0x0 0x0 0x3000 0x0 0x4>;
+
+   cpu_bpmp_tx: bpmp_shmem@4e000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4e000 0x0 0x1000>;
+   };
+
+   cpu_bpmp_rx: bpmp_shmem@4f000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4f000 0x0 0x1000>;
+   };
+   };
+
+   timer {
+   compatible = "arm,armv8-timer";
+   interrupts = ,
+,
+,
+;
+   interrupt-parent = <>;
+   };
+};
-- 
2.9.0



[PATCH 09/10] arm64: dts: tegra: Add NVIDIA Tegra186 P3310 main board support

2016-06-27 Thread Joseph Lo
Add NVIDIA Tegra186 P3310 main board support, which is a chip module
with DRAM, nonvolatile storage, WiFi, ethernet and PMIC chips on it. It
also needs an IO board and hooks on it to represent as an application
platform.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi | 30 ++
 1 file changed, 30 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi

diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
new file mode 100644
index ..5258ec0d6eef
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
@@ -0,0 +1,30 @@
+#include "tegra186.dtsi"
+
+/ {
+   model = "NVIDIA Tegra186 P3310 main Board";
+   compatible = "nvidia,p3301", "nvidia,tegra186";
+
+   aliases {
+   serial0 = 
+   };
+
+   chosen {
+   bootargs = "earlycon console=ttyS0,115200n8";
+   stdout-path = "serial0:115200n8";
+   };
+
+   memory {
+   device_type = "memory";
+   reg = <0x0 0x8000 0x2 0x>;
+   };
+
+   serial@0310 {
+   // HACK: before clk driver ready
+   clock-frequency = <40800>;
+   status = "okay";
+   };
+
+   bpmp@d000 {
+   status = "okay";
+   };
+};
-- 
2.9.0



[PATCH 07/10] arm64: defconfig: Enable Tegra186 SoC

2016-06-27 Thread Joseph Lo
Enable Tegra186 SoC.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f267eea101a7..033d9cb1e983 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -312,6 +312,7 @@ CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD=y
 CONFIG_QCOM_SMD_RPM=y
 CONFIG_ARCH_TEGRA_132_SOC=y
+CONFIG_ARCH_TEGRA_186_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_EXTCON_USB_GPIO=y
 CONFIG_PWM=y
-- 
2.9.0



Re: [PATCH 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-06-28 Thread Joseph Lo

On 06/29/2016 03:08 AM, Stephen Warren wrote:

On 06/28/2016 03:15 AM, Joseph Lo wrote:

On 06/27/2016 11:55 PM, Stephen Warren wrote:

On 06/27/2016 03:02 AM, Joseph Lo wrote:

snip.


Currently the usage of HSP HW in the downstream kernel is something like
the model below.

remote_processor_A-\
remote_processor_B--->hsp@1000 (doorbell func) <-> host CPU
remote_processor_C-/

remote_processor_D -> hsp@2000 (shared mailbox) <-> CPU

remote_processor_E -> hsp@3000 (shared mailbox) <-> CPU

I am thinking if we can just add the appropriate compatible strings for
it to replace "nvidia,tegra186-hsp". e.g. "nvidia,tegra186-hsp-doorbell"
and "nvidia,tegra186-hsp-sharedmailbox". So the driver can probe and
initialize correctly depend on the compatible property. How do you think
about it? Is this the same as the (b) you mentioned above?


Yes, that would be (b) above.

However, please do note (a): I expect that splitting things up will turn
out to be a mistake, as it has for other HW modules in the past. I would
far rather see a single hsp node in DT, since there is a single HSP
block in HW. Sure that block has multiple sub-functions. However, there
is common logic that affects all of those sub-functions and binds
everything into a single HW module. If you represent the HW module using
multiple different DT nodes, it will be hard to correctly represent that
common logic. Conversely, I see no real advantage to splitting up the DT
node. I strongly believe we should have a single "hsp" node in DT.


We have 6 HSP block in HW. FYI.



Internally, the SW driver for that node can be structured however you
want; it could register with multiple subsystems (mailbox, ...) with
just one struct device, or the HSP driver could be an MFD device with
sub-drivers for each separate piece of functionality the HW implements.
All this can easily be done even while using a single DT node. And
furthermore, we can add this SW structure later if/when we actually need
it; in other words, there's no need to change your current patches right
now, except to remove the nvidia,hsp-function DT property.


Thanks,
-Joseph


[PATCH V2 00/10] arm64: tegra: add BPMP support

2016-07-05 Thread Joseph Lo
Hi,

This series introduce the first announced Boot and Power Management Processor
(BPMP) for the new generation Tegra SoCs, which is designed for boot
process handling and offloading the power management tasks from the CPU.

We also add some very initial and basic support for Tegra186 SoC, which
supports debug console and initrd for initial bring up currently. More drivers
and functions can be supported based on this later.

Thanks,
Joseph

Changes in V2
- revise the HSP mailbox and bpmp DT binding documents
- fix the HSP mailbox driver according to the binding update
- update the dts files to represent the binding update

Joseph Lo (10):
  Documentation: dt-bindings: mailbox: tegra: Add binding for HSP
mailbox
  mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives)
driver
  Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP
  firmware: tegra: add IVC library
  firmware: tegra: add BPMP support
  soc/tegra: Add Tegra186 support
  arm64: defconfig: Enable Tegra186 SoC
  arm64: dts: tegra: Add Tegra186 support
  arm64: dts: tegra: Add NVIDIA Tegra186 P3310 main board support
  arm64: dts: tegra: Add NVIDIA P2771 board support

 .../bindings/firmware/nvidia,tegra186-bpmp.txt |   77 +
 .../bindings/mailbox/nvidia,tegra186-hsp.txt   |   51 +
 arch/arm64/boot/dts/nvidia/Makefile|1 +
 arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts |8 +
 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi |   34 +
 arch/arm64/boot/dts/nvidia/tegra186.dtsi   |   77 +
 arch/arm64/configs/defconfig   |1 +
 drivers/firmware/Kconfig   |1 +
 drivers/firmware/Makefile  |1 +
 drivers/firmware/tegra/Kconfig |   25 +
 drivers/firmware/tegra/Makefile|2 +
 drivers/firmware/tegra/bpmp.c  |  713 +
 drivers/firmware/tegra/ivc.c   |  659 
 drivers/mailbox/Kconfig|9 +
 drivers/mailbox/Makefile   |2 +
 drivers/mailbox/tegra-hsp.c|  418 +
 drivers/soc/tegra/Kconfig  |   14 +
 include/dt-bindings/clock/tegra186-clock.h |  940 
 include/dt-bindings/mailbox/tegra186-hsp.h |   23 +
 include/dt-bindings/reset/tegra186-reset.h |  217 +++
 include/soc/tegra/bpmp.h   |   29 +
 include/soc/tegra/bpmp_abi.h   | 1601 
 include/soc/tegra/ivc.h|  102 ++
 23 files changed, 5005 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
 create mode 100644 
Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186.dtsi
 create mode 100644 drivers/firmware/tegra/Kconfig
 create mode 100644 drivers/firmware/tegra/Makefile
 create mode 100644 drivers/firmware/tegra/bpmp.c
 create mode 100644 drivers/firmware/tegra/ivc.c
 create mode 100644 drivers/mailbox/tegra-hsp.c
 create mode 100644 include/dt-bindings/clock/tegra186-clock.h
 create mode 100644 include/dt-bindings/mailbox/tegra186-hsp.h
 create mode 100644 include/dt-bindings/reset/tegra186-reset.h
 create mode 100644 include/soc/tegra/bpmp.h
 create mode 100644 include/soc/tegra/bpmp_abi.h
 create mode 100644 include/soc/tegra/ivc.h

-- 
2.9.0



[PATCH V2 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-07-05 Thread Joseph Lo
Add DT binding for the Hardware Synchronization Primitives (HSP). The
HSP is designed for the processors to share resources and communicate
together. It provides a set of hardware synchronization primitives for
interprocessor communication. So the interprocessor communication (IPC)
protocols can use hardware synchronization primitive, when operating
between two processors not in an SMP relationship.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- revise the compatible string, interrupt-names, interrupts, and #mbox-cells
  properties
- remove "nvidia,hsp-function" property
- fix the header file name
- the binding supports the concept of multiple HSP sub-modules on one HSP HW
  block now.
---
 .../bindings/mailbox/nvidia,tegra186-hsp.txt   | 51 ++
 include/dt-bindings/mailbox/tegra186-hsp.h | 23 ++
 2 files changed, 74 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
 create mode 100644 include/dt-bindings/mailbox/tegra186-hsp.h

diff --git a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt 
b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
new file mode 100644
index ..10e53edbe1c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
@@ -0,0 +1,51 @@
+NVIDIA Tegra Hardware Synchronization Primitives (HSP)
+
+The HSP modules are used for the processors to share resources and communicate
+together. It provides a set of hardware synchronization primitives for
+interprocessor communication. So the interprocessor communication (IPC)
+protocols can use hardware synchronization primitives, when operating between
+two processors not in an SMP relationship.
+
+The features that HSP supported are shared mailboxes, shared semaphores,
+arbitrated semaphores and doorbells.
+
+Required properties:
+- name : Should be hsp
+- compatible
+Array of strings.
+one of:
+- "nvidia,tegra186-hsp"
+- reg : Offset and length of the register set for the device.
+- interrupt-names
+Array of strings.
+Contains a list of names for the interrupts described by the interrupt
+property. May contain the following entries, in any order:
+- "doorbell"
+Users of this binding MUST look up entries in the interrupt property
+by name, using this interrupt-names property to do so.
+- interrupts
+Array of interrupt specifiers.
+Must contain one entry per entry in the interrupt-names property,
+in a matching order.
+- #mbox-cells : Should be 1.
+
+The mbox specifier of the "mboxes" property in the client node should use
+the "HSP_MBOX_ID" macro which integrates the HSP type and master ID data.
+Those information can be found in the following file.
+
+- .
+
+Example:
+
+hsp_top0: hsp@3c0 {
+   compatible = "nvidia,tegra186-hsp";
+   reg = <0x0 0x03c0 0x0 0xa>;
+   interrupts = ;
+   interrupt-names = "doorbell";
+   #mbox-cells = <1>;
+};
+
+client {
+   ...
+   mboxes = <_top0 HSP_MBOX_ID(DB, HSP_DB_MASTER_XXX)>;
+};
diff --git a/include/dt-bindings/mailbox/tegra186-hsp.h 
b/include/dt-bindings/mailbox/tegra186-hsp.h
new file mode 100644
index ..365dbeb5d894
--- /dev/null
+++ b/include/dt-bindings/mailbox/tegra186-hsp.h
@@ -0,0 +1,23 @@
+/*
+ * This header provides constants for binding nvidia,tegra186-hsp.
+ *
+ * The number with HSP_DB_MASTER prefix indicates the bit that is
+ * associated with a master ID in the doorbell registers.
+ */
+
+
+#ifndef _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H
+#define _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H
+
+#define HSP_MBOX_TYPE_DB 0x0
+#define HSP_MBOX_TYPE_SM 0x1
+#define HSP_MBOX_TYPE_SS 0x2
+#define HSP_MBOX_TYPE_AS 0x3
+
+#define HSP_DB_MASTER_CCPLEX 17
+#define HSP_DB_MASTER_BPMP 19
+
+#define HSP_MBOX_ID(type, ID) \
+   (HSP_MBOX_TYPE_##type << 16 | ID)
+
+#endif /* _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H */
-- 
2.9.0



[PATCH V2 06/10] soc/tegra: Add Tegra186 support

2016-07-05 Thread Joseph Lo
The Tegra186 has a combination of Denver and Cortex-A57 CPU cores and
GPUs with Pascal architecture on it. It features with ADSP with
Cortex-A9 CPU for audio processing, hardware video encoder/decoder with
multi-format support, ISP for image capture processing and BPMP for the
power managements.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- None
---
 drivers/soc/tegra/Kconfig | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 03089ad2fc65..88a71dfd466c 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -61,6 +61,20 @@ config ARCH_TEGRA_132_SOC
  but contains an NVIDIA Denver CPU complex in place of
  Tegra124's "4+1" Cortex-A15 CPU complex.
 
+config ARCH_TEGRA_186_SOC
+   bool "NVIDIA Tegra186 SoC"
+   select MAILBOX
+   select TEGRA_BPMP
+   select TEGRA_HSP_MBOX
+   select TEGRA_IVC
+   help
+ Enable support for the NVIDIA Tegar186 SoC. The Tegra186 has a
+ combination of Denver and Cortex-A57 CPU cores and GPUs with Pascal
+ architecture on it. It features with ADSP with Cortex-A9 CPU for
+ audio processing, hardware video encoder/decoder with multi-format
+ support, ISP for image capture processing and BPMP for the power
+ managements.
+
 config ARCH_TEGRA_210_SOC
bool "NVIDIA Tegra210 SoC"
select PINCTRL_TEGRA210
-- 
2.9.0



[PATCH V2 05/10] firmware: tegra: add BPMP support

2016-07-05 Thread Joseph Lo
The Tegra BPMP (Boot and Power Management Processor) is designed for the
booting process handling, offloading the power management tasks and
some system control services from the CPU. It can be clock, DVFS,
thermal/EDP, power gating operation and system suspend/resume handling.
So the CPU and the drivers of these modules can base on the service that
the BPMP firmware driver provided to signal the event for the specific PM
action to BPMP and receive the status update from BPMP.

Comparing to the ARM SCPI, the service provided by BPMP is message-based
communication but not method-based. The BPMP firmware driver provides the
send/receive service for the users, when the user concerns the response
time. If the user needs to get the event or update from the firmware, it
can request the MRQ service as well. The user needs to take care of the
message format, which we call BPMP ABI.

The BPMP ABI defines the message format for different modules or usages.
For example, the clock operation needs an MRQ service code called
MRQ_CLK with specific message format which includes different sub
commands for various clock operations. This is the message format that
BPMP can recognize.

So the user needs two things to initiate IPC between BPMP. Get the
service from the bpmp_ops structure and maintain the message format as
the BPMP ABI defined.

Based-on-the-work-by:
Sivaram Nair <sivar...@nvidia.com>

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- None
---
 drivers/firmware/tegra/Kconfig  |   12 +
 drivers/firmware/tegra/Makefile |1 +
 drivers/firmware/tegra/bpmp.c   |  713 +
 include/soc/tegra/bpmp.h|   29 +
 include/soc/tegra/bpmp_abi.h| 1601 +++
 5 files changed, 2356 insertions(+)
 create mode 100644 drivers/firmware/tegra/bpmp.c
 create mode 100644 include/soc/tegra/bpmp.h
 create mode 100644 include/soc/tegra/bpmp_abi.h

diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig
index 1fa3e4e136a5..ff2730d5c468 100644
--- a/drivers/firmware/tegra/Kconfig
+++ b/drivers/firmware/tegra/Kconfig
@@ -10,4 +10,16 @@ config TEGRA_IVC
  keeps the content is synchronization between host CPU and remote
  processors.
 
+config TEGRA_BPMP
+   bool "Tegra BPMP driver"
+   depends on ARCH_TEGRA && TEGRA_HSP_MBOX && TEGRA_IVC
+   help
+ BPMP (Boot and Power Management Processor) is designed to off-loading
+ the PM functions which include clock/DVFS/thermal/power from the CPU.
+ It needs HSP as the HW synchronization and notification module and
+ IVC module as the message communication protocol.
+
+ This driver manages the IPC interface between host CPU and the
+ firmware running on BPMP.
+
 endmenu
diff --git a/drivers/firmware/tegra/Makefile b/drivers/firmware/tegra/Makefile
index 92e2153e8173..e34a2f79e1ad 100644
--- a/drivers/firmware/tegra/Makefile
+++ b/drivers/firmware/tegra/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_TEGRA_BPMP)   += bpmp.o
 obj-$(CONFIG_TEGRA_IVC)+= ivc.o
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
new file mode 100644
index ..24fda626610e
--- /dev/null
+++ b/drivers/firmware/tegra/bpmp.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define BPMP_MSG_SZ128
+#define BPMP_MSG_DATA_SZ   120
+
+#define __MRQ_ATTRS0xff00
+#define __MRQ_INDEX(id)((id) & ~__MRQ_ATTRS)
+
+#define DO_ACK BIT(0)
+#define RING_DOORBELL  BIT(1)
+
+struct tegra_bpmp_soc_data {
+   u32 ch_index;   /* channel index */
+   u32 thread_ch_index;/* thread channel index */
+   u32 cpu_rx_ch_index;/* CPU Rx channel index */
+   u32 nr_ch;  /* number of total channels */
+   u32 nr_thread_ch;   /* number of thread channels */
+   u32 ch_timeout; /* channel timeout */
+   u32 thread_ch_timeout;  /* thread channel timeout */
+};
+
+struct channel_info {
+   u32 tch_free;
+   u32 tch_to_complete;
+   struct semaphore tch_sem;
+};
+
+struct mb_data {
+   s32 code;
+   s32 flags;
+   u8 data[BPMP_MSG_DATA_SZ];
+} __packed;
+
+struct channel_data {
+   struct mb_data *ib;
+   struct mb_data *ob;
+};
+
+

[PATCH V2 03/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-07-05 Thread Joseph Lo
The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management, clock
management, and reset control tasks from the CPU. The binding document
defines the resources that would be used by the BPMP firmware driver,
which can create the interprocessor communication (IPC) between the CPU
and BPMP.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- update the message that the BPMP is clock and reset control provider
- add tegra186-clock.h and tegra186-reset.h header files
- revise the description of the required properties
---
 .../bindings/firmware/nvidia,tegra186-bpmp.txt |  77 ++
 include/dt-bindings/clock/tegra186-clock.h | 940 +
 include/dt-bindings/reset/tegra186-reset.h | 217 +
 3 files changed, 1234 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
 create mode 100644 include/dt-bindings/clock/tegra186-clock.h
 create mode 100644 include/dt-bindings/reset/tegra186-reset.h

diff --git 
a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt 
b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
new file mode 100644
index ..4d0b6eba56c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
@@ -0,0 +1,77 @@
+NVIDIA Tegra Boot and Power Management Processor (BPMP)
+
+The BPMP is a specific processor in Tegra chip, which is designed for
+booting process handling and offloading the power management, clock
+management, and reset control tasks from the CPU. The binding document
+defines the resources that would be used by the BPMP firmware driver,
+which can create the interprocessor communication (IPC) between the CPU
+and BPMP.
+
+Required properties:
+- name : Should be bpmp
+- compatible
+Array of strings
+One of:
+- "nvidia,tegra186-bpmp"
+- mboxes : The phandle of mailbox controller and the mailbox specifier.
+- shmem : List of the phandle of the TX and RX shared memory area that
+ the IPC between CPU and BPMP is based on.
+- #clock-cells : Should be 1.
+- #reset-cells : Should be 1.
+
+This node is a mailbox consumer. See the following files for details of
+the mailbox subsystem, and the specifiers implemented by the relevant
+provider(s):
+
+- Documentation/devicetree/bindings/mailbox/mailbox.txt
+- Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
+
+This node is a clock and reset provider. See the following files for
+general documentation of those features, and the specifiers implemented
+by this node:
+
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+- include/dt-bindings/clock/tegra186-clock.h
+- Documentation/devicetree/bindings/reset/reset.txt
+- include/dt-bindings/reset/tegra186-reset.h
+
+The shared memory bindings for BPMP
+---
+
+The shared memory area for the IPC TX and RX between CPU and BPMP are
+predefined and work on top of sysram, which is an SRAM inside the chip.
+
+See "Documentation/devicetree/bindings/sram/sram.txt" for the bindings.
+
+Example:
+
+hsp_top0: hsp@03c0 {
+   ...
+   #mbox-cells = <1>;
+};
+
+sysram@3000 {
+   compatible = "nvidia,tegra186-sysram", "mmio-ram";
+   reg = <0x0 0x3000 0x0 0x5>;
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges = <0 0x0 0x0 0x3000 0x0 0x5>;
+
+   cpu_bpmp_tx: bpmp_shmem@4e000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4e000 0x0 0x1000>;
+   };
+
+   cpu_bpmp_rx: bpmp_shmem@4f000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4f000 0x0 0x1000>;
+   };
+};
+
+bpmp {
+   compatible = "nvidia,tegra186-bpmp";
+   mboxes = <_top0 HSP_MBOX_ID(DB, HSP_DB_MASTER_BPMP)>;
+   shmem = <_bpmp_tx _bpmp_rx>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+};
diff --git a/include/dt-bindings/clock/tegra186-clock.h 
b/include/dt-bindings/clock/tegra186-clock.h
new file mode 100644
index ..f73d32098f99
--- /dev/null
+++ b/include/dt-bindings/clock/tegra186-clock.h
@@ -0,0 +1,940 @@
+/** @file */
+
+#ifndef _MACH_T186_CLK_T186_H
+#define _MACH_T186_CLK_T186_H
+
+/**
+ * @defgroup clock_ids Clock Identifiers
+ * @{
+ *   @defgroup extern_input external input clocks
+ *   @{
+ * @def TEGRA186_CLK_OSC
+ * @def TEGRA186_CLK_CLK_32K
+ * @def TEGRA186_CLK_DTV_INPUT
+ * @def TEGRA186_CLK_SOR0_PAD_CLKOUT
+ * @def TEGRA186_CLK_SOR1_PAD_CLKOUT
+ * @def TEGRA186_CLK_I2S1_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S2_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S3_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S4_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S5_SYNC_INPUT
+ * @d

[PATCH V2 04/10] firmware: tegra: add IVC library

2016-07-05 Thread Joseph Lo
The Inter-VM communication (IVC) is a communication protocol, which is
designed for interprocessor communication (IPC) or the communication
between the hypervisor and the virtual machine with a guest OS on it. So
it can be translated as inter-virtual memory or inter-virtual machine
communication. The message channels are maintained on the DRAM or SRAM
and the data coherency should be considered. Or the data could be
corrupted or out of date when the remote client checking it.

Inside the IVC, it maintains memory-based descriptors for the TX/RX
channels and the coherency issue of the counter and payloads. So the
clients can use it to send/receive messages to/from remote ones.

We introduce it as a library for the firmware drivers, which can use it
for IPC.

Based-on-the-work-by:
Peter Newman <pnew...@nvidia.com>

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- None
---
 drivers/firmware/Kconfig|   1 +
 drivers/firmware/Makefile   |   1 +
 drivers/firmware/tegra/Kconfig  |  13 +
 drivers/firmware/tegra/Makefile |   1 +
 drivers/firmware/tegra/ivc.c| 659 
 include/soc/tegra/ivc.h | 102 +++
 6 files changed, 777 insertions(+)
 create mode 100644 drivers/firmware/tegra/Kconfig
 create mode 100644 drivers/firmware/tegra/Makefile
 create mode 100644 drivers/firmware/tegra/ivc.c
 create mode 100644 include/soc/tegra/ivc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 5e618058defe..bbd64ae8c4c6 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -200,5 +200,6 @@ config HAVE_ARM_SMCCC
 source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
+source "drivers/firmware/tegra/Kconfig"
 
 endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 474bada56fcd..9a4df8171cc4 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -24,3 +24,4 @@ obj-y += broadcom/
 obj-$(CONFIG_GOOGLE_FIRMWARE)  += google/
 obj-$(CONFIG_EFI)  += efi/
 obj-$(CONFIG_UEFI_CPER)+= efi/
+obj-y  += tegra/
diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig
new file mode 100644
index ..1fa3e4e136a5
--- /dev/null
+++ b/drivers/firmware/tegra/Kconfig
@@ -0,0 +1,13 @@
+menu "Tegra firmware driver"
+
+config TEGRA_IVC
+   bool "Tegra IVC protocol"
+   depends on ARCH_TEGRA
+   help
+ IVC (Inter-VM Communication) protocol is part of the IPC
+ (Inter Processor Communication) framework on Tegra. It maintains the
+ data and the different commuication channels in SysRAM or RAM and
+ keeps the content is synchronization between host CPU and remote
+ processors.
+
+endmenu
diff --git a/drivers/firmware/tegra/Makefile b/drivers/firmware/tegra/Makefile
new file mode 100644
index ..92e2153e8173
--- /dev/null
+++ b/drivers/firmware/tegra/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TEGRA_IVC)+= ivc.o
diff --git a/drivers/firmware/tegra/ivc.c b/drivers/firmware/tegra/ivc.c
new file mode 100644
index ..3e736bb9915a
--- /dev/null
+++ b/drivers/firmware/tegra/ivc.c
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+
+#include 
+
+#define IVC_ALIGN 64
+
+#ifdef CONFIG_SMP
+
+static inline void ivc_rmb(void)
+{
+   smp_rmb();
+}
+
+static inline void ivc_wmb(void)
+{
+   smp_wmb();
+}
+
+static inline void ivc_mb(void)
+{
+   smp_mb();
+}
+
+#else
+
+static inline void ivc_rmb(void)
+{
+   rmb();
+}
+
+static inline void ivc_wmb(void)
+{
+   wmb();
+}
+
+static inline void ivc_mb(void)
+{
+   mb();
+}
+
+#endif
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum ivc_state {
+   /*
+* This value is zero for backwards compatibility with services that
+* assume channels to be initially zeroed. Such channels are in an
+* initially valid state, but cannot be asynchronously reset, and must
+* maintain a valid state at all times.
+*
+* The transmitting end can enter the established state from the sync or
+* ack state when it observes the receiving endpoint in the ack or
+* established stat

[PATCH V2 07/10] arm64: defconfig: Enable Tegra186 SoC

2016-07-05 Thread Joseph Lo
Enable Tegra186 SoC.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- None
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e69051098435..64d767ec142c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -326,6 +326,7 @@ CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD=y
 CONFIG_QCOM_SMD_RPM=y
 CONFIG_ARCH_TEGRA_132_SOC=y
+CONFIG_ARCH_TEGRA_186_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_EXTCON_USB_GPIO=y
 CONFIG_PWM=y
-- 
2.9.0



[PATCH V2 02/10] mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives) driver

2016-07-05 Thread Joseph Lo
The Tegra HSP mailbox driver implements the signaling doorbell-based
interprocessor communication (IPC) for remote processors currently. The
HSP HW modules support some different features for that, which are
shared mailboxes, shared semaphores, arbitrated semaphores, and
doorbells. And there are multiple HSP HW instances on the chip. So the
driver is extendable to support more features for different IPC
requirement.

The driver of remote processor can use it as a mailbox client and deal
with the IPC protocol to synchronize the data communications.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- Update the driver to support the binding changes in V2
- it's extendable to support multiple HSP sub-modules on the same HSP HW block
  now.
---
 drivers/mailbox/Kconfig |   9 +
 drivers/mailbox/Makefile|   2 +
 drivers/mailbox/tegra-hsp.c | 418 
 3 files changed, 429 insertions(+)
 create mode 100644 drivers/mailbox/tegra-hsp.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 5305923752d2..fe584cb54720 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -114,6 +114,15 @@ config MAILBOX_TEST
  Test client to help with testing new Controller driver
  implementations.
 
+config TEGRA_HSP_MBOX
+   bool "Tegra HSP(Hardware Synchronization Primitives) Driver"
+   depends on ARCH_TEGRA_186_SOC
+   help
+ The Tegra HSP driver is used for the interprocessor communication
+ between different remote processors and host processors on Tegra186
+ and later SoCs. Say Y here if you want to have this support.
+ If unsure say N.
+
 config XGENE_SLIMPRO_MBOX
tristate "APM SoC X-Gene SLIMpro Mailbox Controller"
depends on ARCH_XGENE
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 0be3e742bb7d..26d8f91c7fea 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -25,3 +25,5 @@ obj-$(CONFIG_TI_MESSAGE_MANAGER) += ti-msgmgr.o
 obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o
 
 obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
+
+obj-${CONFIG_TEGRA_HSP_MBOX}   += tegra-hsp.o
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
new file mode 100644
index ..93c3ef58f29f
--- /dev/null
+++ b/drivers/mailbox/tegra-hsp.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HSP_INT_DIMENSIONING   0x380
+#define HSP_nSM_OFFSET 0
+#define HSP_nSS_OFFSET 4
+#define HSP_nAS_OFFSET 8
+#define HSP_nDB_OFFSET 12
+#define HSP_nSI_OFFSET 16
+#define HSP_nINT_MASK  0xf
+
+#define HSP_DB_REG_TRIGGER 0x0
+#define HSP_DB_REG_ENABLE  0x4
+#define HSP_DB_REG_RAW 0x8
+#define HSP_DB_REG_PENDING 0xc
+
+#define HSP_DB_CCPLEX  1
+#define HSP_DB_BPMP3
+
+#define MAX_NUM_HSP_CHAN 32
+#define MAX_NUM_HSP_DB 7
+
+#define hsp_db_offset(i, d) \
+   (d->base + ((1 + (d->nr_sm >> 1) + d->nr_ss + d->nr_as) << 16) + \
+   (i) * 0x100)
+
+struct tegra_hsp_db_chan {
+   int master_id;
+   int db_id;
+};
+
+struct tegra_hsp_mbox_chan {
+   int type;
+   union {
+   struct tegra_hsp_db_chan db_chan;
+   };
+};
+
+struct tegra_hsp_mbox {
+   struct mbox_controller *mbox;
+   void __iomem *base;
+   void __iomem *db_base[MAX_NUM_HSP_DB];
+   int db_irq;
+   int nr_sm;
+   int nr_as;
+   int nr_ss;
+   int nr_db;
+   int nr_si;
+   spinlock_t lock;
+};
+
+static inline u32 hsp_readl(void __iomem *base, int reg)
+{
+   return readl(base + reg);
+}
+
+static inline void hsp_writel(void __iomem *base, int reg, u32 val)
+{
+   writel(val, base + reg);
+   readl(base + reg);
+}
+
+static int hsp_db_can_ring(void __iomem *db_base)
+{
+   u32 reg;
+
+   reg = hsp_readl(db_base, HSP_DB_REG_ENABLE);
+
+   return !!(reg & BIT(HSP_DB_MASTER_CCPLEX));
+}
+
+static irqreturn_t hsp_db_irq(int irq, void *p)
+{
+   struct tegra_hsp_mbox *hsp_mbox = p;
+   ulong val;
+   int master_id;
+
+   val = (ulong)hsp_readl(hsp_mbox->db_base[HSP_DB_CCPLEX],
+  HSP_DB_REG_PENDING);
+   hsp_writel(hsp_mbox->db_base[HSP_DB_CCPLEX], HSP_DB_REG_PENDING, val);
+
+ 

[PATCH V2 09/10] arm64: dts: tegra: Add NVIDIA Tegra186 P3310 main board support

2016-07-05 Thread Joseph Lo
Add NVIDIA Tegra186 P3310 main board support, which is a chip module
with DRAM, nonvolatile storage, WiFi, ethernet and PMIC chips on it. It
also needs an IO board and hooks on it to represent as an application
platform.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- update according to the binding fix in V2
---
 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi | 34 ++
 1 file changed, 34 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi

diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
new file mode 100644
index ..f5238866d321
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
@@ -0,0 +1,34 @@
+#include "tegra186.dtsi"
+
+/ {
+   model = "NVIDIA Tegra186 P3310 main Board";
+   compatible = "nvidia,p3301", "nvidia,tegra186";
+
+   aliases {
+   serial0 = 
+   };
+
+   chosen {
+   bootargs = "earlycon console=ttyS0,115200n8";
+   stdout-path = "serial0:115200n8";
+   };
+
+   memory {
+   device_type = "memory";
+   reg = <0x0 0x8000 0x2 0x>;
+   };
+
+   serial@0310 {
+   // HACK: before clk driver ready
+   clock-frequency = <40800>;
+   status = "okay";
+   };
+
+   hsp@03c0 {
+   status = "okay";
+   };
+
+   bpmp {
+   status = "okay";
+   };
+};
-- 
2.9.0



[PATCH V2 10/10] arm64: dts: tegra: Add NVIDIA P2771 board support

2016-07-05 Thread Joseph Lo
Add NVIDIA Tegra186 P2771 board support, which is a reference
development board with P2597 I/O board and P3310 chip module on it.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- None
---
 arch/arm64/boot/dts/nvidia/Makefile| 1 +
 arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts | 8 
 2 files changed, 9 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts

diff --git a/arch/arm64/boot/dts/nvidia/Makefile 
b/arch/arm64/boot/dts/nvidia/Makefile
index 0f7cdf3e05c1..67234f3dc795 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -1,4 +1,5 @@
 dtb-$(CONFIG_ARCH_TEGRA_132_SOC) += tegra132-norrin.dtb
+dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts 
b/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts
new file mode 100644
index ..66b936389fa7
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "tegra186-p3310.dtsi"
+
+/ {
+   model = "NVIDIA Tegra186 P2771- Board";
+   compatible = "nvidia,p2771-", "nvidia,tegra186";
+};
-- 
2.9.0



[PATCH V2 08/10] arm64: dts: tegra: Add Tegra186 support

2016-07-05 Thread Joseph Lo
This adds the initial support of Tegra186 SoC, which can help to bring
up the debug console and initrd for further developing.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- update the file according the HSP and BPMP binding fix in V2
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 77 
 1 file changed, 77 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186.dtsi

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
new file mode 100644
index ..57badd5de9b4
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -0,0 +1,77 @@
+#include 
+#include 
+
+/ {
+   compatible = "nvidia,tegra186";
+   interrupt-parent = <>;
+   #address-cells = <2>;
+   #size-cells = <2>;
+
+   uarta: serial@0310 {
+   compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+   reg = <0x0 0x0310 0x0 0x40>;
+   reg-shift = <2>;
+   interrupts = ;
+   status = "disabled";
+   };
+
+   gic: interrupt-controller@03881000 {
+   compatible = "arm,gic-400";
+   #interrupt-cells = <3>;
+   interrupt-controller;
+   reg = <0x0 0x03881000 0x0 0x1000>,
+ <0x0 0x03882000 0x0 0x2000>;
+   interrupts = ;
+   interrupt-parent = <>;
+   };
+
+   hsp_top0: hsp@03c0 {
+   compatible = "nvidia,tegra186-hsp";
+   reg = <0x0 0x03c0 0x0 0xa>;
+   interrupts = ;
+   interrupt-names = "doorbell";
+   #mbox-cells = <1>;
+   status = "disabled";
+   };
+
+   sysram@3000 {
+   compatible = "nvidia,tegra186-sysram", "mmio-ram";
+   reg = <0x0 0x3000 0x0 0x4>;
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges = <0 0x0 0x0 0x3000 0x0 0x4>;
+
+   cpu_bpmp_tx: bpmp_shmem@4e000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4e000 0x0 0x1000>;
+   };
+
+   cpu_bpmp_rx: bpmp_shmem@4f000 {
+   compatible = "nvidia,tegra186-bpmp-shmem";
+   reg = <0x0 0x4f000 0x0 0x1000>;
+   };
+   };
+
+   bpmp {
+   compatible = "nvidia,tegra186-bpmp";
+   mboxes = <_top0 HSP_MBOX_ID(DB, HSP_DB_MASTER_BPMP)>;
+   shmem = <_bpmp_tx _bpmp_rx>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   status = "disabled";
+   };
+
+   timer {
+   compatible = "arm,armv8-timer";
+   interrupts = ,
+,
+,
+;
+   interrupt-parent = <>;
+   };
+};
-- 
2.9.0



Re: [PATCH V2 03/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-07-07 Thread Joseph Lo

On 07/06/2016 07:42 PM, Alexandre Courbot wrote:

On Tue, Jul 5, 2016 at 6:04 PM, Joseph Lo <jose...@nvidia.com> wrote:

The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management, clock
management, and reset control tasks from the CPU. The binding document
defines the resources that would be used by the BPMP firmware driver,
which can create the interprocessor communication (IPC) between the CPU
and BPMP.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- update the message that the BPMP is clock and reset control provider
- add tegra186-clock.h and tegra186-reset.h header files
- revise the description of the required properties
---
  .../bindings/firmware/nvidia,tegra186-bpmp.txt |  77 ++
  include/dt-bindings/clock/tegra186-clock.h | 940 +
  include/dt-bindings/reset/tegra186-reset.h | 217 +
  3 files changed, 1234 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
  create mode 100644 include/dt-bindings/clock/tegra186-clock.h
  create mode 100644 include/dt-bindings/reset/tegra186-reset.h

diff --git 
a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt 
b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
new file mode 100644
index ..4d0b6eba56c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
@@ -0,0 +1,77 @@
+NVIDIA Tegra Boot and Power Management Processor (BPMP)
+
+The BPMP is a specific processor in Tegra chip, which is designed for
+booting process handling and offloading the power management, clock
+management, and reset control tasks from the CPU. The binding document
+defines the resources that would be used by the BPMP firmware driver,
+which can create the interprocessor communication (IPC) between the CPU
+and BPMP.
+
+Required properties:
+- name : Should be bpmp
+- compatible
+Array of strings
+One of:
+- "nvidia,tegra186-bpmp"
+- mboxes : The phandle of mailbox controller and the mailbox specifier.
+- shmem : List of the phandle of the TX and RX shared memory area that
+ the IPC between CPU and BPMP is based on.
+- #clock-cells : Should be 1.
+- #reset-cells : Should be 1.
+
+This node is a mailbox consumer. See the following files for details of
+the mailbox subsystem, and the specifiers implemented by the relevant
+provider(s):
+
+- Documentation/devicetree/bindings/mailbox/mailbox.txt
+- Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
+
+This node is a clock and reset provider. See the following files for
+general documentation of those features, and the specifiers implemented
+by this node:
+
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+- include/dt-bindings/clock/tegra186-clock.h
+- Documentation/devicetree/bindings/reset/reset.txt
+- include/dt-bindings/reset/tegra186-reset.h
+
+The shared memory bindings for BPMP
+---
+
+The shared memory area for the IPC TX and RX between CPU and BPMP are
+predefined and work on top of sysram, which is an SRAM inside the chip.
+
+See "Documentation/devicetree/bindings/sram/sram.txt" for the bindings.
+
+Example:
+
+hsp_top0: hsp@03c0 {
+   ...
+   #mbox-cells = <1>;
+};
+
+sysram@3000 {
+   compatible = "nvidia,tegra186-sysram", "mmio-ram";


Shouldn't the second compatible be "mmio-sram"?

If so, then you have the same typo in tegra186.dtsi as well.



Good catch, will fix.

Thanks,
-Joseph


Re: [PATCH V2 03/10] Documentation: dt-bindings: firmware: tegra: add bindings of the BPMP

2016-07-07 Thread Joseph Lo

On 07/07/2016 01:03 AM, Stephen Warren wrote:

On 07/05/2016 03:04 AM, Joseph Lo wrote:

The BPMP is a specific processor in Tegra chip, which is designed for
booting process handling and offloading the power management, clock
management, and reset control tasks from the CPU. The binding document
defines the resources that would be used by the BPMP firmware driver,
which can create the interprocessor communication (IPC) between the CPU
and BPMP.


Acked-by: Stephen Warren <swar...@nvidia.com>


Thanks,
-Joseph


Re: [PATCH V2 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-07-07 Thread Joseph Lo

On 07/07/2016 01:02 AM, Stephen Warren wrote:

On 07/05/2016 03:04 AM, Joseph Lo wrote:

Add DT binding for the Hardware Synchronization Primitives (HSP). The
HSP is designed for the processors to share resources and communicate
together. It provides a set of hardware synchronization primitives for
interprocessor communication. So the interprocessor communication (IPC)
protocols can use hardware synchronization primitive, when operating
between two processors not in an SMP relationship.


Acked-by: Stephen Warren <swar...@nvidia.com>


Thanks,
-Joseph


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


Re: [PATCH V2 02/10] mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives) driver

2016-07-07 Thread Joseph Lo

On 07/06/2016 08:23 PM, Alexandre Courbot wrote:

On Wed, Jul 6, 2016 at 6:06 PM, Joseph Lo <jose...@nvidia.com> wrote:

On 07/06/2016 03:05 PM, Alexandre Courbot wrote:


On Tue, Jul 5, 2016 at 6:04 PM, Joseph Lo <jose...@nvidia.com> wrote:


The Tegra HSP mailbox driver implements the signaling doorbell-based
interprocessor communication (IPC) for remote processors currently. The
HSP HW modules support some different features for that, which are
shared mailboxes, shared semaphores, arbitrated semaphores, and
doorbells. And there are multiple HSP HW instances on the chip. So the
driver is extendable to support more features for different IPC
requirement.

The driver of remote processor can use it as a mailbox client and deal
with the IPC protocol to synchronize the data communications.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- Update the driver to support the binding changes in V2
- it's extendable to support multiple HSP sub-modules on the same HSP HW
block
now.
---
   drivers/mailbox/Kconfig |   9 +
   drivers/mailbox/Makefile|   2 +
   drivers/mailbox/tegra-hsp.c | 418

   3 files changed, 429 insertions(+)
   create mode 100644 drivers/mailbox/tegra-hsp.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 5305923752d2..fe584cb54720 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -114,6 +114,15 @@ config MAILBOX_TEST
Test client to help with testing new Controller driver
implementations.

+config TEGRA_HSP_MBOX
+   bool "Tegra HSP(Hardware Synchronization Primitives) Driver"



Space missing before the opening parenthesis (same in the patch title
btw).


Okay.




+   depends on ARCH_TEGRA_186_SOC
+   help
+ The Tegra HSP driver is used for the interprocessor
communication
+ between different remote processors and host processors on
Tegra186
+ and later SoCs. Say Y here if you want to have this support.
+ If unsure say N.



Since this option is selected automatically by ARCH_TEGRA_186_SOC, you
should probably drop the last 2 sentences.


Okay.




+
   config XGENE_SLIMPRO_MBOX
  tristate "APM SoC X-Gene SLIMpro Mailbox Controller"
  depends on ARCH_XGENE
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 0be3e742bb7d..26d8f91c7fea 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -25,3 +25,5 @@ obj-$(CONFIG_TI_MESSAGE_MANAGER) += ti-msgmgr.o
   obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o

   obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
+
+obj-${CONFIG_TEGRA_HSP_MBOX}   += tegra-hsp.o
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
new file mode 100644
index ..93c3ef58f29f
--- /dev/null
+++ b/drivers/mailbox/tegra-hsp.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HSP_INT_DIMENSIONING   0x380
+#define HSP_nSM_OFFSET 0
+#define HSP_nSS_OFFSET 4
+#define HSP_nAS_OFFSET 8
+#define HSP_nDB_OFFSET 12
+#define HSP_nSI_OFFSET 16



Would be nice to have comments to understand what SM, SS, AS, etc.
stand for (Shared Mailboxes, Shared Semaphores, Arbitrated Semaphores
but you need to look at the patch description to understand that). A
top-of-file comment explaning the necessary concepts to read this code
would do the trick.


Yes, will fix that.




+#define HSP_nINT_MASK  0xf
+
+#define HSP_DB_REG_TRIGGER 0x0
+#define HSP_DB_REG_ENABLE  0x4
+#define HSP_DB_REG_RAW 0x8
+#define HSP_DB_REG_PENDING 0xc
+
+#define HSP_DB_CCPLEX  1
+#define HSP_DB_BPMP3



Maybe turn this into enum and use that type for
tegra_hsp_db_chan::db_id? Also have MAX_NUM_HSP_DB here, since it is
related to these values?


Okay.




+
+#define MAX_NUM_HSP_CHAN 32
+#define MAX_NUM_HSP_DB 7
+
+#define hsp_db_offset(i, d) \
+   (d->base + ((1 + (d->nr_sm >> 1) + d->nr_ss + d->nr_as) << 16) +
\
+   (i) * 0x100)
+
+struct tegra_hsp_db_chan {
+   int master_id;
+   int db_id;
+};
+
+struct tegra_hsp_mbox_chan {
+   int type;
+   union {
+   struct tegra_hsp_db_chan db_chan;
+   };
+};
+
+struct tegra_hsp_mbox {
+   struct mbox_controller *mbox;
+   vo

Re: [PATCH V2 02/10] mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives) driver

2016-07-07 Thread Joseph Lo

On 07/07/2016 12:50 AM, Stephen Warren wrote:

On 07/06/2016 03:06 AM, Joseph Lo wrote:

On 07/06/2016 03:05 PM, Alexandre Courbot wrote:

On Tue, Jul 5, 2016 at 6:04 PM, Joseph Lo <jose...@nvidia.com> wrote:

The Tegra HSP mailbox driver implements the signaling doorbell-based
interprocessor communication (IPC) for remote processors currently. The
HSP HW modules support some different features for that, which are
shared mailboxes, shared semaphores, arbitrated semaphores, and
doorbells. And there are multiple HSP HW instances on the chip. So the
driver is extendable to support more features for different IPC
requirement.

The driver of remote processor can use it as a mailbox client and deal
with the IPC protocol to synchronize the data communications.



diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c



+static irqreturn_t hsp_db_irq(int irq, void *p)
+{
+   struct tegra_hsp_mbox *hsp_mbox = p;
+   ulong val;
+   int master_id;
+
+   val = (ulong)hsp_readl(hsp_mbox->db_base[HSP_DB_CCPLEX],
+  HSP_DB_REG_PENDING);
+   hsp_writel(hsp_mbox->db_base[HSP_DB_CCPLEX],
HSP_DB_REG_PENDING, val);
+
+   spin_lock(_mbox->lock);
+   for_each_set_bit(master_id, , MAX_NUM_HSP_CHAN) {
+   struct mbox_chan *chan;
+   struct tegra_hsp_mbox_chan *mchan;
+   int i;
+
+   for (i = 0; i < MAX_NUM_HSP_CHAN; i++) {


I wonder if this could not be optimized. You are doing a double loop
on MAX_NUM_HSP_CHAN to look for an identical master_id. Since it seems
like the same master_id cannot be used twice (considering that the
inner loop only processes the first match), couldn't you just select
the free channel in of_hsp_mbox_xlate() by doing
>chans[master_id] (and returning an error if it is already
used), then simply getting chan as _mbox->mbox->chans[master_id]
instead of having the inner loop below? That would remove the need for
the second loop.


That was exactly what I did in the V1, which only supported one HSP
sub-module per HSP HW block. So we can just use the master_id as the
mbox channel ID.

Meanwhile, the V2 is purposed to support multiple HSP sub-modules to be
running on the same HSP HW block. The "ID" between different modules
could be conflict. So I dropped the mechanism that used the master_id as
the mbox channel ID.


I haven't looked at the code in this patch since I'm mainly concerned
about the DT bindings. However, I will say that nothing in the change to
the mailbox specifier in DT should have required /any/ changes to the
code, except to add a single check to validate that the "mailbox type"
encoded into the top 16 bits of the mailbox ID were 0, and hence
represented a doorbell rather than anything else. Any enhancements to
support other mailbox types could have happened later, and I doubt would
require anything dynamic even then.


Yes, I only add the code for that change. Maybe some glue code for the 
extend-ability to support more HSP modules in the future.





+static int tegra_hsp_db_init(struct tegra_hsp_mbox *hsp_mbox,
+struct mbox_chan *mchan, int master_id)
+{
+   struct platform_device *pdev =
to_platform_device(hsp_mbox->mbox->dev);
+   struct tegra_hsp_mbox_chan *hsp_mbox_chan;
+   int ret;
+
+   if (!hsp_mbox->db_irq) {
+   int i;
+
+   hsp_mbox->db_irq = platform_get_irq_byname(pdev,
"doorbell");


Getting the IRQ sounds more like a job for probe() - I don't see the
benefit of lazy-doing it?


We only need the IRQ when the client is requesting the DB service. For
other HSP sub-modules, they are using different IRQ. So I didn't do that
at probe time.


All resources provided by other devices/drivers must be acquired at
probe time, since that's the only time it's possible to defer probe if
the provider of the resource is not available.

If you don't follow that rule, what happens is:

1) This driver probes.

2) Some other driver calls tegra_hsp_db_init(), and it fails since the
provider of the IRQ is not yet available. This likely ends up returning
something other than -EPROBE_DEFER since the HSP driver was found
successfully (thus there is no deferred probe situation as far as the
mailbox core is concerned), it's just that the mailbox channel
lookup/init/... failed.

3) The other driver's probe() fails due to this, but since the error
wasn't a probe deferral, the other driver's probe() is never retried.


Agree, will fix this.

Thanks,
-Joseph


Re: [PATCH V2 05/10] firmware: tegra: add BPMP support

2016-07-07 Thread Joseph Lo

On 07/06/2016 07:39 PM, Alexandre Courbot wrote:

Sorry, I will probably need to do several passes on this one to
understand everything, but here is what I can say after a first look:

On Tue, Jul 5, 2016 at 6:04 PM, Joseph Lo <jose...@nvidia.com> wrote:

The Tegra BPMP (Boot and Power Management Processor) is designed for the
booting process handling, offloading the power management tasks and
some system control services from the CPU. It can be clock, DVFS,
thermal/EDP, power gating operation and system suspend/resume handling.
So the CPU and the drivers of these modules can base on the service that
the BPMP firmware driver provided to signal the event for the specific PM
action to BPMP and receive the status update from BPMP.

Comparing to the ARM SCPI, the service provided by BPMP is message-based
communication but not method-based. The BPMP firmware driver provides the
send/receive service for the users, when the user concerns the response
time. If the user needs to get the event or update from the firmware, it
can request the MRQ service as well. The user needs to take care of the
message format, which we call BPMP ABI.

The BPMP ABI defines the message format for different modules or usages.
For example, the clock operation needs an MRQ service code called
MRQ_CLK with specific message format which includes different sub
commands for various clock operations. This is the message format that
BPMP can recognize.

So the user needs two things to initiate IPC between BPMP. Get the
service from the bpmp_ops structure and maintain the message format as
the BPMP ABI defined.

Based-on-the-work-by:
Sivaram Nair <sivar...@nvidia.com>

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- None
---
  drivers/firmware/tegra/Kconfig  |   12 +
  drivers/firmware/tegra/Makefile |1 +
  drivers/firmware/tegra/bpmp.c   |  713 +
  include/soc/tegra/bpmp.h|   29 +
  include/soc/tegra/bpmp_abi.h| 1601 +++
  5 files changed, 2356 insertions(+)
  create mode 100644 drivers/firmware/tegra/bpmp.c
  create mode 100644 include/soc/tegra/bpmp.h
  create mode 100644 include/soc/tegra/bpmp_abi.h

diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig
index 1fa3e4e136a5..ff2730d5c468 100644
--- a/drivers/firmware/tegra/Kconfig
+++ b/drivers/firmware/tegra/Kconfig
@@ -10,4 +10,16 @@ config TEGRA_IVC
   keeps the content is synchronization between host CPU and remote
   processors.

+config TEGRA_BPMP
+   bool "Tegra BPMP driver"
+   depends on ARCH_TEGRA && TEGRA_HSP_MBOX && TEGRA_IVC
+   help
+ BPMP (Boot and Power Management Processor) is designed to off-loading


s/off-loading/off-load


+ the PM functions which include clock/DVFS/thermal/power from the CPU.
+ It needs HSP as the HW synchronization and notification module and
+ IVC module as the message communication protocol.
+
+ This driver manages the IPC interface between host CPU and the
+ firmware running on BPMP.
+
  endmenu
diff --git a/drivers/firmware/tegra/Makefile b/drivers/firmware/tegra/Makefile
index 92e2153e8173..e34a2f79e1ad 100644
--- a/drivers/firmware/tegra/Makefile
+++ b/drivers/firmware/tegra/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_TEGRA_BPMP)   += bpmp.o
  obj-$(CONFIG_TEGRA_IVC)+= ivc.o
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
new file mode 100644
index ..24fda626610e
--- /dev/null
+++ b/drivers/firmware/tegra/bpmp.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define BPMP_MSG_SZ128
+#define BPMP_MSG_DATA_SZ   120
+
+#define __MRQ_ATTRS0xff00
+#define __MRQ_INDEX(id)((id) & ~__MRQ_ATTRS)
+
+#define DO_ACK BIT(0)
+#define RING_DOORBELL  BIT(1)
+
+struct tegra_bpmp_soc_data {
+   u32 ch_index;   /* channel index */
+   u32 thread_ch_index;/* thread channel index */
+   u32 cpu_rx_ch_index;/* CPU Rx channel index */
+   u32 nr_ch;  /* number of total channels */
+   u32 nr_thread_ch;   /* number of thread channels */
+   u32 ch_timeout; /* channel timeout */
+   u32 thread_ch_timeout;  /* thread channel timeout */
+};


With jus

Re: [PATCH V2 02/10] mailbox: tegra-hsp: Add HSP(Hardware Synchronization Primitives) driver

2016-07-06 Thread Joseph Lo

On 07/06/2016 03:05 PM, Alexandre Courbot wrote:

On Tue, Jul 5, 2016 at 6:04 PM, Joseph Lo <jose...@nvidia.com> wrote:

The Tegra HSP mailbox driver implements the signaling doorbell-based
interprocessor communication (IPC) for remote processors currently. The
HSP HW modules support some different features for that, which are
shared mailboxes, shared semaphores, arbitrated semaphores, and
doorbells. And there are multiple HSP HW instances on the chip. So the
driver is extendable to support more features for different IPC
requirement.

The driver of remote processor can use it as a mailbox client and deal
with the IPC protocol to synchronize the data communications.

Signed-off-by: Joseph Lo <jose...@nvidia.com>
---
Changes in V2:
- Update the driver to support the binding changes in V2
- it's extendable to support multiple HSP sub-modules on the same HSP HW block
   now.
---
  drivers/mailbox/Kconfig |   9 +
  drivers/mailbox/Makefile|   2 +
  drivers/mailbox/tegra-hsp.c | 418 
  3 files changed, 429 insertions(+)
  create mode 100644 drivers/mailbox/tegra-hsp.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 5305923752d2..fe584cb54720 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -114,6 +114,15 @@ config MAILBOX_TEST
   Test client to help with testing new Controller driver
   implementations.

+config TEGRA_HSP_MBOX
+   bool "Tegra HSP(Hardware Synchronization Primitives) Driver"


Space missing before the opening parenthesis (same in the patch title btw).

Okay.



+   depends on ARCH_TEGRA_186_SOC
+   help
+ The Tegra HSP driver is used for the interprocessor communication
+ between different remote processors and host processors on Tegra186
+ and later SoCs. Say Y here if you want to have this support.
+ If unsure say N.


Since this option is selected automatically by ARCH_TEGRA_186_SOC, you
should probably drop the last 2 sentences.

Okay.



+
  config XGENE_SLIMPRO_MBOX
 tristate "APM SoC X-Gene SLIMpro Mailbox Controller"
 depends on ARCH_XGENE
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 0be3e742bb7d..26d8f91c7fea 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -25,3 +25,5 @@ obj-$(CONFIG_TI_MESSAGE_MANAGER) += ti-msgmgr.o
  obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o

  obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
+
+obj-${CONFIG_TEGRA_HSP_MBOX}   += tegra-hsp.o
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
new file mode 100644
index ..93c3ef58f29f
--- /dev/null
+++ b/drivers/mailbox/tegra-hsp.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HSP_INT_DIMENSIONING   0x380
+#define HSP_nSM_OFFSET 0
+#define HSP_nSS_OFFSET 4
+#define HSP_nAS_OFFSET 8
+#define HSP_nDB_OFFSET 12
+#define HSP_nSI_OFFSET 16


Would be nice to have comments to understand what SM, SS, AS, etc.
stand for (Shared Mailboxes, Shared Semaphores, Arbitrated Semaphores
but you need to look at the patch description to understand that). A
top-of-file comment explaning the necessary concepts to read this code
would do the trick.

Yes, will fix that.



+#define HSP_nINT_MASK  0xf
+
+#define HSP_DB_REG_TRIGGER 0x0
+#define HSP_DB_REG_ENABLE  0x4
+#define HSP_DB_REG_RAW 0x8
+#define HSP_DB_REG_PENDING 0xc
+
+#define HSP_DB_CCPLEX  1
+#define HSP_DB_BPMP3


Maybe turn this into enum and use that type for
tegra_hsp_db_chan::db_id? Also have MAX_NUM_HSP_DB here, since it is
related to these values?

Okay.



+
+#define MAX_NUM_HSP_CHAN 32
+#define MAX_NUM_HSP_DB 7
+
+#define hsp_db_offset(i, d) \
+   (d->base + ((1 + (d->nr_sm >> 1) + d->nr_ss + d->nr_as) << 16) + \
+   (i) * 0x100)
+
+struct tegra_hsp_db_chan {
+   int master_id;
+   int db_id;
+};
+
+struct tegra_hsp_mbox_chan {
+   int type;
+   union {
+   struct tegra_hsp_db_chan db_chan;
+   };
+};
+
+struct tegra_hsp_mbox {
+   struct mbox_controller *mbox;
+   void __iomem *base;
+   void __iomem *db_base[MAX_NUM_HSP_DB];
+   int db_irq;
+   int nr_sm;
+   int nr_as;
+   int nr_ss;
+   int nr_db;
+

Re: [PATCH 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-06-30 Thread Joseph Lo

On 06/29/2016 11:28 PM, Stephen Warren wrote:

On 06/28/2016 11:56 PM, Joseph Lo wrote:

On 06/29/2016 03:08 AM, Stephen Warren wrote:

On 06/28/2016 03:15 AM, Joseph Lo wrote:

On 06/27/2016 11:55 PM, Stephen Warren wrote:

On 06/27/2016 03:02 AM, Joseph Lo wrote:

snip.


Currently the usage of HSP HW in the downstream kernel is something
like
the model below.

remote_processor_A-\
remote_processor_B--->hsp@1000 (doorbell func) <-> host CPU
remote_processor_C-/

remote_processor_D -> hsp@2000 (shared mailbox) <-> CPU

remote_processor_E -> hsp@3000 (shared mailbox) <-> CPU

I am thinking if we can just add the appropriate compatible strings for
it to replace "nvidia,tegra186-hsp". e.g.
"nvidia,tegra186-hsp-doorbell"
and "nvidia,tegra186-hsp-sharedmailbox". So the driver can probe and
initialize correctly depend on the compatible property. How do you
think
about it? Is this the same as the (b) you mentioned above?


Yes, that would be (b) above.

However, please do note (a): I expect that splitting things up will turn
out to be a mistake, as it has for other HW modules in the past. I would
far rather see a single hsp node in DT, since there is a single HSP
block in HW. Sure that block has multiple sub-functions. However, there
is common logic that affects all of those sub-functions and binds
everything into a single HW module. If you represent the HW module using
multiple different DT nodes, it will be hard to correctly represent that
common logic. Conversely, I see no real advantage to splitting up the DT
node. I strongly believe we should have a single "hsp" node in DT.


We have 6 HSP block in HW. FYI.


Yes, we have 6 /instances/ of the overall HSP block. Those should each
have their own node, since they're entirely separate modules, all
instances of the same configurable IP block.

Above, I was talking about the sub-blocks within each HSP instance,
which should all be represented into a single node per instance, for a
total of 6 DT nodes overall.

Yes.

So, one thing still concerns me is that the binding and driver still 
can't work with multiple HSP sub-modules per HSP block. It only supports 
one HSP module per HSP block right how. Although, I said it matches the 
model that we are using in the downstream kernel. But I still concern if 
we need to enable and work with multiple HSP modules per HSP block at 
sometime in future, then the binding and driver need lots of change to 
achieve that. And the binding is not back-ward compatible obviously.


So I want to revise it again.

#mbox-cells: should be 2.

The mobxes property in the client node should contain the phandle of the 
HSP block, HSP sub-module ID and the specifier of the module.


Ex.
hsp_top0: hsp@1000 {
...
#mbox-cells = <2>;
};

clientA {

mboxes = <_top0 HSP_DOORBELL DB_MASTER_XXX>;
};

clientB {
...
mboxes = <_top0 HSP_SHARED_MAILBOX SM_MASTER_XXX>;
};

Stephen, How do you think of this change?

Thanks,
-Joseph


Re: [PATCH 01/10] Documentation: dt-bindings: mailbox: tegra: Add binding for HSP mailbox

2016-06-30 Thread Joseph Lo

On 07/01/2016 12:02 AM, Stephen Warren wrote:

On 06/30/2016 03:25 AM, Joseph Lo wrote:

On 06/29/2016 11:28 PM, Stephen Warren wrote:

On 06/28/2016 11:56 PM, Joseph Lo wrote:

On 06/29/2016 03:08 AM, Stephen Warren wrote:

On 06/28/2016 03:15 AM, Joseph Lo wrote:

On 06/27/2016 11:55 PM, Stephen Warren wrote:

On 06/27/2016 03:02 AM, Joseph Lo wrote:

snip.


Currently the usage of HSP HW in the downstream kernel is something
like
the model below.

remote_processor_A-\
remote_processor_B--->hsp@1000 (doorbell func) <-> host CPU
remote_processor_C-/

remote_processor_D -> hsp@2000 (shared mailbox) <-> CPU

remote_processor_E -> hsp@3000 (shared mailbox) <-> CPU

I am thinking if we can just add the appropriate compatible strings
for
it to replace "nvidia,tegra186-hsp". e.g.
"nvidia,tegra186-hsp-doorbell"
and "nvidia,tegra186-hsp-sharedmailbox". So the driver can probe and
initialize correctly depend on the compatible property. How do you
think
about it? Is this the same as the (b) you mentioned above?


Yes, that would be (b) above.

However, please do note (a): I expect that splitting things up will
turn
out to be a mistake, as it has for other HW modules in the past. I
would
far rather see a single hsp node in DT, since there is a single HSP
block in HW. Sure that block has multiple sub-functions. However,
there
is common logic that affects all of those sub-functions and binds
everything into a single HW module. If you represent the HW module
using
multiple different DT nodes, it will be hard to correctly represent
that
common logic. Conversely, I see no real advantage to splitting up
the DT
node. I strongly believe we should have a single "hsp" node in DT.


We have 6 HSP block in HW. FYI.


Yes, we have 6 /instances/ of the overall HSP block. Those should each
have their own node, since they're entirely separate modules, all
instances of the same configurable IP block.

Above, I was talking about the sub-blocks within each HSP instance,
which should all be represented into a single node per instance, for a
total of 6 DT nodes overall.

Yes.

So, one thing still concerns me is that the binding and driver still
can't work with multiple HSP sub-modules per HSP block. It only supports
one HSP module per HSP block right how.


The driver can be enhanced without affecting the DT binding, providing
the binding is reasonably designed, as I believe it is.

I believe the existing binding can work fine for multiple HSP
sub-modules, or at least be extended in a backwards-compatible way.
Aside from the mailbox cells issue you mention below, is there any other
reason you believe the binding can't be extended in a
backwards-compatible way? Interrupts are already accessed solely by
name, so we can add more later without issue. The node can become a
provider for any other resource type besides mailboxes in a
backwards-compatible way without issue.


Because the mbox client has no idea to know which hsb sub-module to bind 
with. However, the way you suggested below should solve my concern and 
back-ward compatible indeed.





Although, I said it matches the
model that we are using in the downstream kernel. But I still concern if
we need to enable and work with multiple HSP modules per HSP block at
sometime in future, then the binding and driver need lots of change to
achieve that. And the binding is not back-ward compatible obviously.

So I want to revise it again.

#mbox-cells: should be 2.

The mobxes property in the client node should contain the phandle of the
HSP block, HSP sub-module ID and the specifier of the module.

Ex.
hsp_top0: hsp@1000 {
 ...
 #mbox-cells = <2>;
};

clientA {
 
 mboxes = <_top0 HSP_DOORBELL DB_MASTER_XXX>;
};

clientB {
 ...
 mboxes = <_top0 HSP_SHARED_MAILBOX SM_MASTER_XXX>;
};

Stephen, How do you think of this change?


Well, we could do that. Or, since we won't have 2^32 instances of
doorbells, we could also have #mbox-cells=<1> as we do now, and encode
mailbox IDs as "(type << 16) | id" where TEGRA186_HSP_MAILBOX_TYPE_DB is
0. That would be backwards-compatible with no change to the binding. I
think either way is fine. I have a slight preference for keeping
#mbox-cells=<1> to avoid revising the U-Boot driver code I wrote, but I
can deal with changing it if I have to.


Ah, yes. I think the U-Boot doesn't need to deal with the multiple HSP 
sub-module supporting issue, and the binding I purposed was more 
complicate for that. The idea with "#mbox-cells=<1>" and 
"mboxes=<(type<<16)|id>" is fine with me. I will revise the hsp driver 
for this.


Thanks,
-Joseph


Re: [PATCH 2/5] cpufreq: star/stop cpufreq timers on cpu hotplug

2013-01-29 Thread Joseph Lo
On Wed, 2013-01-30 at 12:52 +0800, Viresh Kumar wrote:
> Hi Fabio,
> 
> Sorry for waking up very late :)
> 
> The reason why i am starting this thread again is due to problem
> reported by Joseph,
> with latest linux-next/master branch (which contains few big patches
> from me :) ):
> 
After Viresh point me out what patch may cause the issue that I met
below, I also try to just revert this patch on linux-next. Then
everything that may trigger to disable_nonboot_cpus or hotplug back to
normal. So just reverting this patch also fix the issues I saw.
FYI.

Thanks,
Joseph

> Reboot is giving following to him:
> 
> * Will now halt
> [ 193.756068] Disabling non-boot CPUs...
> [ 193.760088] BUG: scheduling while atomic: halt/780/0x0002
> [ 193.765845] Modules linked in: brcmfmac brcmutil
> [ 193.770613] [] (unwind_backtrace+0x0/0xf8) from []
> (__schedule_bug+0x44/0x5c)
> [ 193.779548] [] (__schedule_bug+0x44/0x5c) from []
> (__schedule+0x688/0x6ec)
> [ 193.788206] [] (__schedule+0x688/0x6ec) from []
> (schedule_preempt_disabled+0x24/0x34)
> [ 193.797811] [] (schedule_preempt_disabled+0x24/0x34) from
> [] (__mutex_lock_slowpath+0x170/0x34c)
> [ 193.808367] [] (__mutex_lock_slowpath+0x170/0x34c) from
> [] (mutex_lock+0xc/0x24)
> [ 193.817554] [] (mutex_lock+0xc/0x24) from []
> (unregister_cpu_notifier+0xc/0x24)
> [ 193.826640] [] (unregister_cpu_notifier+0xc/0x24) from
> [] (cpufreq_governor_dbs+0x118/0x614)
> [ 193.836866] [] (cpufreq_governor_dbs+0x118/0x614) from
> [] (__cpufreq_governor+0x58/0xc0)
> [ 193.846737] [] (__cpufreq_governor+0x58/0xc0) from
> [] (__cpufreq_remove_dev.clone.7+0x58/0x320)
> [ 193.857207] [] (__cpufreq_remove_dev.clone.7+0x58/0x320)
> from [] (cpufreq_cpu_callback+0x8c/0x9c)
> [ 193.867850] [] (cpufreq_cpu_callback+0x8c/0x9c) from
> [] (notifier_call_chain+0x44/0x84)
> [ 193.877623] [] (notifier_call_chain+0x44/0x84) from
> [] (__cpu_notify+0x2c/0x48)
> [ 193.886704] [] (__cpu_notify+0x2c/0x48) from []
> (_cpu_down+0xb0/0x23c)
> [ 193.895004] [] (_cpu_down+0xb0/0x23c) from []
> (disable_nonboot_cpus+0x68/0x104)
> [ 193.904089] [] (disable_nonboot_cpus+0x68/0x104) from
> [] (kernel_power_off+0x24/0x48)
> [ 193.913688] [] (kernel_power_off+0x24/0x48) from
> [] (sys_reboot+0x104/0x1e0)
> [ 193.922517] [] (sys_reboot+0x104/0x1e0) from []
> (ret_fast_syscall+0x0/0x30)
> 
> 
> And the crash log show this patch of yours somewhere :)
> 
> First question: Is this patch still required? Because following patch from me 
> is
> sending a STOP/START to governors on cpu hot-[un]plug ?
> 
> commit dbcb63407c095af73f3464767e00902cdee55e8b
> Author: Viresh Kumar 
> Date:   Sat Jan 12 05:14:39 2013 +
> 
> cpufreq: Notify governors when cpus are hot-[un]plugged
> 
> 
> For me, the answer is NO.
> 
> Over that, i tried these patches on ARM bigLITTLE TC2 (3 A7's  and 2 A15's) 
> and
> my system wasn't booting at all for ondemand governor. Reverting your patch 
> does
> fix the issue:
> 
> [2.613573] arm_big_little: bL_cpufreq_init: Initialized, cpu: 0, cluster 0
> [2.635436] arm_big_little: bL_cpufreq_init: Initialized, cpu: 2, cluster 1
> [   23.650184] INFO: rcu_sched self-detected stall on CPU { 0}
> (t=2100 jiffies g=4294967088 c=4294967087 q=10)
> [   23.679664] Backtrace for cpu 0 (current):
> [   23.680239] INFO: rcu_sched detected stalls on CPUs/tasks: { 0}
> (detected by 2, t=2103 jiffies, g=4294967088, c=4294967087, q=10)
> [   23.726839] [] (unwind_backtrace+0x0/0xf8) from
> [] (smp_send_all_cpu_backtrace+0x60/0xcc)
> [   23.756545] [] (smp_send_all_cpu_backtrace+0x60/0xcc)
> from [] (rcu_pending+0x2c8/0x63c)
> [   23.785731] [] (rcu_pending+0x2c8/0x63c) from
> [] (rcu_check_callbacks+0x7c/0x148)
> [   23.813358] [] (rcu_check_callbacks+0x7c/0x148) from
> [] (update_process_times+0x38/0x68)
> [   23.842808] [] (update_process_times+0x38/0x68) from
> [] (tick_sched_handle+0x48/0x54)
> [   23.871472] [] (tick_sched_handle+0x48/0x54) from
> [] (tick_sched_timer+0x44/0x74)
> [   23.899098] [] (tick_sched_timer+0x44/0x74) from
> [] (__run_hrtimer+0x84/0x1b4)
> [   23.925940] [] (__run_hrtimer+0x84/0x1b4) from
> [] (hrtimer_interrupt+0x108/0x2d4)
> [   23.953563] [] (hrtimer_interrupt+0x108/0x2d4) from
> [] (arch_timer_handler_virt+0x30/0x38)
> [   23.983530] [] (arch_timer_handler_virt+0x30/0x38) from
> [] (handle_percpu_devid_irq+0x74/0x110)
> [   24.014799] [] (handle_percpu_devid_irq+0x74/0x110) from
> [] (generic_handle_irq+0x20/0x30)
> [   24.044765] [] (generic_handle_irq+0x20/0x30) from
> [] (handle_IRQ+0x38/0x94)
> [   24.071085] [] (handle_IRQ+0x38/0x94) from []
> (gic_handle_irq+0x28/0x5c)
> [   24.096362] [] (gic_handle_irq+0x28/0x5c) from
> [] (__irq_svc+0x40/0x50)
> [   24.121374] Exception stack(0xef047ec0 to 0xef047f08)
> [   24.136492] 7ec0:  c0591780  c0591798 c0591780
> c05d5d60  c0593280
> [   24.160986] 7ee0: c0552c98 c02b1df4 ef046000  c059179c
> ef047f08 c03b5f84 c0043698
> [   24.185477] 7f00: a113 
> [   

Re: CPU hotplug hang due to "swap: make each swap partition have one address_space"

2013-02-03 Thread Joseph Lo
On Mon, 2013-02-04 at 10:36 +0800, Shaohua Li wrote:
> On Fri, Feb 01, 2013 at 10:02:33PM -0700, Stephen Warren wrote:
> > Shaohua,
> > 
> > In next-20130128, commit 174f064 "swap: make each swap partition have
> > one address_space" (from the mm/akpm tree) appears causes a hang/RCU
> > stall for me when hot-unplugging a CPU.
> 
> does this one work for you?
> http://marc.info/?l=linux-mm=135929599505624=2
> Or try a more recent linux-next. The patch is in akpm's tree.
> 
Hi Shaohua,

The patch you pointed out did fix the issue. Just verified on Tegra
device.

Thanks,
Joseph


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 06/21] ARM: tegra: call cpu_do_idle from C code

2013-04-23 Thread Joseph Lo
On Wed, 2013-04-24 at 00:30 +0800, Arnd Bergmann wrote:
> When building a kernel for multiple CPU architecture levels,
> cpu_do_idle() is a macro for an indirect function call, which
> cannot be called from assembly code as Tegra does.
> 
> Adding a trivial C wrapper for this function lets us build
> a tegra kernel with ARMv6 support enabled.
> 
> Signed-off-by: Arnd Bergmann 
> Cc: Joseph Lo 
> Cc: Stephen Warren 
> ---

Hi Arnd,

Thanks for fixing.

Tested-by: Joseph Lo 

Joseph

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/21] ARM: tegra: unify tegra_idle_device definitions

2013-04-23 Thread Joseph Lo
On Wed, 2013-04-24 at 06:04 +0800, Daniel Lezcano wrote:
> On 04/23/2013 08:57 PM, Arnd Bergmann wrote:
> > On Tuesday 23 April 2013, Daniel Lezcano wrote:
> >> the patch sounds good but I think the side effect of the consolidation
> >> patchset [1] fixed that.
> >>
> >> You can find these fixes in Rafael's tree:
> >>
> >> https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-nextid=4c637b2175a0dc65d533494225525c6c82d73293
> >>
> >> https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-nextid=e158f9da6974cc11bfab2246a9b10021af0e0d8a
> >>
> >> https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-nextid=c5106c9dea9a6022ab84c6cb1d4a0b19fc5af0e2
> >>
> >> https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-nextid=f040c26ffaa5e56f2bca427c719c9601a02e70e5
> >>
> >> [1] http://www.spinics.net/lists/arm-kernel/msg239811.html
> >>
> > 
> > Ah. Is that not in linux-next? I created the patch today based on the latest
> > linux-next from today (Tuesday).
> 
> Ah, ok. Actually the patches were taken by Rafael right today. So it is
> possible the changes were not reflected in linux-next yet.
> 
Hi Arnd and Daniel,

Thanks for taking care this.:)

Joseph

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] clk: tegra114: table driven PMC clock init

2013-09-03 Thread Joseph Lo
On Tue, 2013-09-03 at 21:31 +0800, Peter De Schrijver wrote:
> This patch converts the Tegra114 audio clock registration to be table driven
> like the periph clocks.
s/audio/PMC/ :)
> 
> Signed-off-by: Peter De Schrijver 
> ---
>  drivers/clk/tegra/clk-tegra114.c |   58 
> +++---
>  1 files changed, 23 insertions(+), 35 deletions(-)
> 
[snip]


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/32] arm: delete __cpuinit/__CPUINIT usage from all ARM users

2013-07-02 Thread Joseph Lo
Adding linux-tegra in Cc.

On Tue, 2013-06-25 at 03:30 +0800, Paul Gortmaker wrote:
> The __cpuinit type of throwaway sections might have made sense
> some time ago when RAM was more constrained, but now the savings
> do not offset the cost and complications.  For example, the fix in
> commit 5e427ec2d0 ("x86: Fix bit corruption at CPU resume time")
> is a good example of the nasty type of bugs that can be created
> with improper use of the various __init prefixes.
> 
> After a discussion on LKML[1] it was decided that cpuinit should go
> the way of devinit and be phased out.  Once all the users are gone,
> we can then finally remove the macros themselves from linux/init.h.
> 
> Note that some harmless section mismatch warnings may result, since
> notify_cpu_starting() and cpu_up() are arch independent (kernel/cpu.c)
> and are flagged as __cpuinit  -- so if we remove the __cpuinit from
> the arch specific callers, we will also get section mismatch warnings.
> As an intermediate step, we intend to turn the linux/init.h cpuinit
> related content into no-ops as early as possible, since that will get
> rid of these warnings.  In any case, they are temporary and harmless.
> 
> This removes all the ARM uses of the __cpuinit macros from C code,
> and all __CPUINIT from assembly code.  It also had two ".previous"
> section statements that were paired off against __CPUINIT
> (aka .section ".cpuinit.text") that also get removed here.
> 
> [1] https://lkml.org/lkml/2013/5/20/589
> 
> Cc: Russell King 
> Cc: Will Deacon 
> Cc: linux-arm-ker...@lists.infradead.org
> Signed-off-by: Paul Gortmaker 
> ---
> 
> [This commit is part of the __cpuinit removal work.  If you don't see
>  any problems with it, then you don't have to do anything ; it will be
>  submitted with all the rest of the __cpuinit removal work.  On the
>  other hand, if you want to carry this patch in with your other pending
>  changes so as to handle conflicts with other pending work yourself, then
>  that is fine too, as the commits can largely be treated independently.
>  For more information, please see: https://lkml.org/lkml/2013/6/20/513 ]
> 

Hi Paul,

I just tested this series on Tegra platform. It looks broken CPU hotplug
function for Tegra at least. The CPU can't plug-in after unplugging. And
the system resume function also not working when "enable_nonboot_cpus".

Both of the issue cause system hang up. Are we missing something for
__cpuinit removal work?

Thanks,
Joseph

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 04/10] memory: Add Tegra124 memory controller support

2014-06-27 Thread Joseph Lo

Hi Thierry,

On 06/27/2014 04:49 AM, Thierry Reding wrote:
[snip]

+
+#define MC_INTSTATUS 0x000
+#define  MC_INT_DECERR_MTS (1 << 16)
+#define  MC_INT_SECERR_SEC (1 << 13)
+#define  MC_INT_DECERR_VPR (1 << 12)
+#define  MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
+#define  MC_INT_INVALID_SMMU_PAGE (1 << 10)
+#define  MC_INT_ARBITRATION_EMEM (1 << 9)
+#define  MC_INT_SECURITY_VIOLATION (1 << 8)
+#define  MC_INT_DECERR_EMEM (1 << 6)
+#define MC_INTMASK 0x004
+#define MC_ERR_STATUS 0x08
+#define MC_ERR_ADR 0x0c
+

[snip]

+
+#define SMMU_PDE_ATTR  (SMMU_PDE_READABLE | SMMU_PDE_WRITABLE | \
+SMMU_PDE_NONSECURE)
+#define SMMU_PTE_ATTR  (SMMU_PTE_READABLE | SMMU_PTE_WRITABLE | \
+SMMU_PTE_NONSECURE)
+
+#define SMMU_PDE_VACANT(n) (((n) << 10) | SMMU_PDE_ATTR)
+#define SMMU_PTE_VACANT(n) (((n) << 12) | SMMU_PTE_ATTR)


There is an ISR to catch the invalid SMMU translation. Do you want to 
modify the identity mapping with read/write attribute of the unused SMMU 
pages?


This can make sure we capture the invalid SMMU translation. And helps 
for driver to capture issues when using SMMU.


-joseph


+static irqreturn_t tegra124_mc_irq(int irq, void *data)
+{
+   struct tegra_mc *mc = data;
+   u32 value, status, mask;
+
+   /* mask all interrupts to avoid flooding */
+   mask = mc_readl(mc, MC_INTMASK);
+   mc_writel(mc, 0, MC_INTMASK);
+
+   status = mc_readl(mc, MC_INTSTATUS);
+   mc_writel(mc, status, MC_INTSTATUS);
+
+   dev_dbg(mc->dev, "INTSTATUS: %08x\n", status);
+
+   if (status & MC_INT_DECERR_MTS)
+   dev_dbg(mc->dev, "  DECERR_MTS\n");
+
+   if (status & MC_INT_SECERR_SEC)
+   dev_dbg(mc->dev, "  SECERR_SEC\n");
+
+   if (status & MC_INT_DECERR_VPR)
+   dev_dbg(mc->dev, "  DECERR_VPR\n");
+
+   if (status & MC_INT_INVALID_APB_ASID_UPDATE)
+   dev_dbg(mc->dev, "  INVALID_APB_ASID_UPDATE\n");
+
+   if (status & MC_INT_INVALID_SMMU_PAGE)
+   dev_dbg(mc->dev, "  INVALID_SMMU_PAGE\n");
+
+   if (status & MC_INT_ARBITRATION_EMEM)
+   dev_dbg(mc->dev, "  ARBITRATION_EMEM\n");
+
+   if (status & MC_INT_SECURITY_VIOLATION)
+   dev_dbg(mc->dev, "  SECURITY_VIOLATION\n");
+
+   if (status & MC_INT_DECERR_EMEM)
+   dev_dbg(mc->dev, "  DECERR_EMEM\n");
+
+   value = mc_readl(mc, MC_ERR_STATUS);
+
+   dev_dbg(mc->dev, "ERR_STATUS: %08x\n", value);
+   dev_dbg(mc->dev, "  type: %x\n", (value >> 28) & 0x7);
+   dev_dbg(mc->dev, "  protection: %x\n", (value >> 25) & 0x7);
+   dev_dbg(mc->dev, "  adr_hi: %x\n", (value >> 20) & 0x3);
+   dev_dbg(mc->dev, "  swap: %x\n", (value >> 18) & 0x1);
+   dev_dbg(mc->dev, "  security: %x\n", (value >> 17) & 0x1);
+   dev_dbg(mc->dev, "  r/w: %x\n", (value >> 16) & 0x1);
+   dev_dbg(mc->dev, "  adr1: %x\n", (value >> 12) & 0x7);
+   dev_dbg(mc->dev, "  client: %x\n", value & 0x7f);
+
+   value = mc_readl(mc, MC_ERR_ADR);
+   dev_dbg(mc->dev, "ERR_ADR: %08x\n", value);
+
+   mc_writel(mc, mask, MC_INTMASK);
+
+   return IRQ_HANDLED;
+}
+

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] cpuidle: coupled: fix the potensial race condition and deadlock

2012-12-02 Thread Joseph Lo
Considering the chance that two CPU come into cpuidle_enter_state_coupled at
very close time. The 1st CPU increases the waiting count and the 2nd CPU do the
same thing right away. The 2nd CPU found the 1st CPU already in waiting then
prepare to poke it.

Before the 2nd CPU to poke 1st CPU, the 1st found the waiting count already same
with cpu_online count. So the 1st won't go into waiting loop and the 2nd CPU
didn't poke it yet. The 1st CPU will go into ready loop directly.

Then the 2nd CPU set up the couple_cpuidle_mask for 1st CPU and poke it. But the
1st CPU already lost the chance to handle the poke and clear the
couple_cpuidle_mask. Now whole MPcore are alredy to be coupled. The MPcore will
go into the power saving idle mode.

Because the poke was be implemented as a "smp_call_function_single", it's a
software intrrupt of "IPI_SINGLE_FUNC". If the power saving idle mode of the
platform can't retain the software interrupt of power saving idle mode, (e.g.
Tegra's powerd-down idle mode will shut off cpu power that include the power of
GIC) the software interrupt will got lost.

When the CPU resumed from the power saving idle mode and the system still keep
idle, it will go into idle mode again immediately. Because the
"smp_call_function_single" not allow the same function be called for the same
cpu twice, or it will got a lock. So the "couple_cpuidle_mask" can't be cleared
by 1st CPU, the 2nd CPU also can't poke it again. Then the deadlock happens
here.

The fix here used different wake up mechanism. Because there are already two
loops and a gloable variable "ready_waiting_counts" to sync the status of
MPcore to coupled state, the "coupled_cpuidle_mask" was not really necessary.
Just waking up the CPU from waiting and checking if the CPU need resched at
outside world to take the CPU out of idle are enough. And this fix didn't
modify the original behavior of coupled cpuidle framework. It should still
compitable with the origianal. The cpuidle driver that already applies
coupled cpuidle not need to change as well.

Cc: Colin Cross 
Signed-off-by: Joseph Lo 
---
Please check the detail sequence about how race condition and deadlock
be happened below:
It could be reproduced on Tegra20 and Tegra30.
(Suppose the last two cpu came into coupled_cpuidle_state at very close time)

CPU_0   CPU_1
cpuidle_enter_state_coupled
cpuidle_enter_state_coupled
1.increase waiting count
1. increase waiting count
 same time frame ---
2.before went into waiting
  loop, check the waiting
  count first
  2.1 the waiting count
   was same with online
   count
  2.2 so it won't go into
   waiting loop
2.in the procedure to prepare to send an
 "smp_call_function_single" to wake up CPU_0
 next time frame ---
3.before go into ready loop
  3.1 it will enable_irq
  3.2 check if there is any
IPI
  3.3 if yes, clear the coupled_mask
  3.4 then disable_irq
3. trigger the IPI to CPU_0
 3.1 set up the coupled_mask for CPU_0
 3.2 sent IPI to CPU_0
4. the IPI_SINGLE_FUNC been triggered from CPU_1 to CPU_0 and the coupled_mask
  of CPU_0 been set up
  4.1 but the CPU_0 miss the IPI and the chance to clear coupled_mask
 next time frame ---
5. MPCores went into ready loop and been coupled
6. go into power saving idle mode
   (For Tegra, it's means the vdd_cpu rail be shut off. The GIC be powered off
and the SW_INT(IPI) couldn't be retained.)
7. After the resume of power saving idle mode, the coupled_mask of CPU_0 not
   been cleared.
8. return to kernel

If the system still idle, it will come back to idle immediately.

CPU_0   CPU_1
cpuidle_enter_state_coupled
cpuidle_enter_state_coupled
1. set itself to waiting
2. go into waiting loop
3. check the coupled_mask been
  set or not
  3.1 enable_irq
  3.2 waiting for the coupled_mask
be cleared

1. found CPU_0 in waiting
2. prepare an IPI to poke CPU_0
  2.1 check the coupled_mask of CPU_0
  2.2 because it had been set
  2.3 so it didn't trigger and
"smp_call_function_single" to CPU_0 again
3. then go into ready loop


Re: [PATCH v3 0/9] Migrate Tegra to common clock framework

2013-01-04 Thread Joseph Lo
On Fri, 2013-01-04 at 17:40 +0800, Prashant Gaikwad wrote:
> This patchset does following:
> 1. Decompose single tegra clock structure into multiple clocks.
> 2. Try to use standard clock types supported by common clock framework.
> 3. Use dynamic initialization.
> 4. Move all clock code to drivers/clk/tegra from mach-tegra.
> 5. Add device tree support for Tegra20 and Tegra30 clocks.
> 6. Remove all legacy clock code from mach-tegra.
> 
> Tested on Tegra30 (Cardhu) and Tegra20 (Ventana).
> 
> Changes from v2:
> Removed APB MISC node.
> Fixed some issues reported by Joseph Lo.
> Added function to read chip id revision register.
> 
> Changes from v1:
> Rebased on linux-next for 20121224.
> 
> Prashant Gaikwad (8):
>   ARM: tegra: Add function to read chipid
>   clk: tegra: Add tegra specific clocks
>   arm: tegra: Move tegra_cpu_car.h to linux/clk/tegra.h
>   ARM: Tegra: Define Tegra30 CAR binding
>   clk: tegra: add clock support for tegra20
>   clk: tegra: add clock support for tegra30
>   arm: tegra: Migrate to new clock code
>   arm: tegra: Remove legacy clock code
> 
> Stephen Warren (1):
>   ARM: tegra: Define Tegra20 CAR binding
> 

Good job, Prashant. :-)

This series :
Tested-by: Joseph Lo 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/7] ARM: dt: tegra20: Add clock information

2013-01-04 Thread Joseph Lo
On Fri, 2013-01-04 at 17:46 +0800, Prashant Gaikwad wrote:
> Add clock information to device nodes.
> 
> Signed-off-by: Prashant Gaikwad 
> ---
> Tested on Ventana (Tegra20) and Cardhu (Tegra30).
> This series depends on ccf-rework patch series.
> ---

This series :
Tested-by: Joseph Lo 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks

2019-07-16 Thread Joseph Lo




On 7/16/19 2:35 PM, Sowjanya Komatineni wrote:


On 7/15/19 10:37 PM, Dmitry Osipenko wrote:

В Mon, 15 Jul 2019 21:37:09 -0700
Sowjanya Komatineni  пишет:


On 7/15/19 8:50 PM, Dmitry Osipenko wrote:

16.07.2019 6:00, Sowjanya Komatineni пишет:

On 7/15/19 5:35 PM, Sowjanya Komatineni wrote:

On 7/14/19 2:41 PM, Dmitry Osipenko wrote:

13.07.2019 8:54, Sowjanya Komatineni пишет:

On 6/29/19 8:10 AM, Dmitry Osipenko wrote:

28.06.2019 5:12, Sowjanya Komatineni пишет:

This patch adds system suspend and resume support for Tegra210
clocks.

All the CAR controller settings are lost on suspend when core
power goes off.

This patch has implementation for saving and restoring all
the PLLs and clocks context during system suspend and resume
to have the clocks back to same state for normal operation.

Acked-by: Thierry Reding 
Signed-off-by: Sowjanya Komatineni 
---
     drivers/clk/tegra/clk-tegra210.c | 115
++-
     drivers/clk/tegra/clk.c  |  14 +
     drivers/clk/tegra/clk.h  |   1 +
     3 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/tegra/clk-tegra210.c
b/drivers/clk/tegra/clk-tegra210.c
index 1c08c53482a5..1b839544e086 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -9,10 +9,12 @@
     #include 
     #include 
     #include 
+#include 
     #include 
     #include 
     #include 
     #include 
+#include 
     #include 
     #include 
     #include 
@@ -20,6 +22,7 @@
     #include 
       #include "clk.h"
+#include "clk-dfll.h"
     #include "clk-id.h"
       /*
@@ -225,6 +228,7 @@
       #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
     #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
+#define CPU_SOFTRST_CTRL 0x380
       #define LVL2_CLK_GATE_OVRA 0xf8
     #define LVL2_CLK_GATE_OVRC 0x3a0
@@ -2820,6 +2824,7 @@ static int tegra210_enable_pllu(void)
     struct tegra_clk_pll_freq_table *fentry;
     struct tegra_clk_pll pllu;
     u32 reg;
+    int ret;
       for (fentry = pll_u_freq_table; fentry->input_rate;
fentry++) {
     if (fentry->input_rate == pll_ref_freq)
@@ -2847,10 +2852,10 @@ static int tegra210_enable_pllu(void)
     fence_udelay(1, clk_base);
     reg |= PLL_ENABLE;
     writel(reg, clk_base + PLLU_BASE);
+    fence_udelay(1, clk_base);
     -    readl_relaxed_poll_timeout_atomic(clk_base +
PLLU_BASE, reg,
-  reg & PLL_BASE_LOCK, 2, 1000);
-    if (!(reg & PLL_BASE_LOCK)) {
+    ret = tegra210_wait_for_mask(, PLLU_BASE,
PLL_BASE_LOCK);
+    if (ret) {
     pr_err("Timed out waiting for PLL_U to lock\n");
     return -ETIMEDOUT;
     }
@@ -3283,6 +3288,103 @@ static void
tegra210_disable_cpu_clock(u32 cpu)
     }
       #ifdef CONFIG_PM_SLEEP
+static u32 cpu_softrst_ctx[3];
+static struct platform_device *dfll_pdev;
+#define car_readl(_base, _off) readl_relaxed(clk_base +
(_base) + ((_off) * 4))
+#define car_writel(_val, _base, _off) \
+    writel_relaxed(_val, clk_base + (_base) + ((_off) *
4)) +
+static int tegra210_clk_suspend(void)
+{
+    unsigned int i;
+    struct device_node *node;
+
+    tegra_cclkg_burst_policy_save_context();
+
+    if (!dfll_pdev) {
+    node = of_find_compatible_node(NULL, NULL,
+   "nvidia,tegra210-dfll");
+    if (node)
+    dfll_pdev = of_find_device_by_node(node);
+
+    of_node_put(node);
+    if (!dfll_pdev)
+    pr_err("dfll node not found. no suspend for
dfll\n");
+    }
+
+    if (dfll_pdev)
+    tegra_dfll_suspend(dfll_pdev);
+
+    /* Enable PLLP_OUT_CPU after dfll suspend */
+    tegra_clk_set_pllp_out_cpu(true);
+
+    tegra_sclk_cclklp_burst_policy_save_context();
+
+    clk_save_context();
+
+    for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
+    cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i);
+
+    return 0;
+}
+
+static void tegra210_clk_resume(void)
+{
+    unsigned int i;
+    struct clk_hw *parent;
+    struct clk *clk;
+
+    /*
+ * clk_restore_context restores clocks as per the clock
tree.
+ *
+ * dfllCPU_out is first in the clock tree to get
restored and it
+ * involves programming DFLL controller along with
restoring CPUG
+ * clock burst policy.
+ *
+ * DFLL programming needs dfll_ref and dfll_soc
peripheral clocks
+ * to be restores which are part ofthe peripheral
clocks.

   ^ white-space

Please use spellchecker to avoid typos.

+ * So, peripheral clocks restore should happen prior to
dfll clock
+ * restore.
+ */
+
+    tegra_clk_osc_resume(clk_base);
+    for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
+    car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i);
+
+    /* restore all plls and peripheral clocks */
+    tegra210_init_pllu();
+    clk_restore_context();
+
+    fence_udelay(5, clk_base);
+
+    /* resume SCLK and CPULP clocks */
+    

Re: [PATCH 1/6] dt-bindings: timer: add Tegra210 timer

2019-01-27 Thread Joseph Lo

On 1/25/19 8:01 PM, Jon Hunter wrote:


On 25/01/2019 03:23, Joseph Lo wrote:

Hi Jon,

Thanks for reviewing.

On 1/24/19 6:30 PM, Jon Hunter wrote:


On 07/01/2019 03:28, Joseph Lo wrote:

The Tegra210 timer provides fourteen 29-bit timer counters and one
32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate
derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator
clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: Joseph Lo 
---
   .../bindings/timer/nvidia,tegra210-timer.txt  | 25 +++
   1 file changed, 25 insertions(+)
   create mode 100644
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

diff --git
a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index ..ba511220a669
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,25 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one
32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate
derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator
clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot,
periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 4 interrupts; one per each of TMR10 through
TMR13.



[snip]

And notice that only TMR10-TMR13 are running at the oscillator clock
(clk_m). With the Tegra210 timer driver, we introduce in this series,
which only replace the clock event device function that was originally
owned by the arch timer (armv8 timer) and it also running at the
oscillator clock. The sched_timer still owns by the arch timer. So the
timer resolution will be the same. That's why we choose TMR10-TMR13 as
the timer for Tegra210.


That maybe fine, but DT should describe the hardware and so I don't see
why we would not list all the interrupts. We can still only use TMR10-13
in the driver.



Okay, will list all the interrupts for each timer channel.

Thanks,
Joseph


[PATCH V2 2/6] clocksource: tegra: add Tegra210 timer driver

2019-01-28 Thread Joseph Lo
Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Based on the work of Antti P Miettinen 

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
---
v2:
 * add error clean-up code
---
 drivers/clocksource/Kconfig  |   3 +
 drivers/clocksource/Makefile |   1 +
 drivers/clocksource/timer-tegra210.c | 268 +++
 include/linux/cpuhotplug.h   |   1 +
 4 files changed, 273 insertions(+)
 create mode 100644 drivers/clocksource/timer-tegra210.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..e6e3e64b6320 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -135,6 +135,9 @@ config TEGRA_TIMER
help
  Enables support for the Tegra driver.
 
+config TEGRA210_TIMER
+   def_bool ARCH_TEGRA_210_SOC
+
 config VT8500_TIMER
bool "VT8500 timer driver" if COMPILE_TEST
depends on HAS_IOMEM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cdd210ff89ea..95de59c8a47b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o
 obj-$(CONFIG_SUN5I_HSTIMER)+= timer-sun5i.o
 obj-$(CONFIG_MESON6_TIMER) += timer-meson6.o
 obj-$(CONFIG_TEGRA_TIMER)  += timer-tegra20.o
+obj-$(CONFIG_TEGRA210_TIMER)   += timer-tegra210.o
 obj-$(CONFIG_VT8500_TIMER) += timer-vt8500.o
 obj-$(CONFIG_NSPIRE_TIMER) += timer-zevio.o
 obj-$(CONFIG_BCM_KONA_TIMER)   += bcm_kona_timer.o
diff --git a/drivers/clocksource/timer-tegra210.c 
b/drivers/clocksource/timer-tegra210.c
new file mode 100644
index ..477b164e540b
--- /dev/null
+++ b/drivers/clocksource/timer-tegra210.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2019, NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static u32 tegra210_timer_freq;
+static void __iomem *tegra210_timer_reg_base;
+static u32 usec_config;
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+#define TIMERUS_CNTR_1US   0x10
+#define TIMERUS_USEC_CFG   0x14
+
+#define TIMER10_OFFSET 0x90
+#define TIMER10_IRQ_IDX10
+
+#define TIMER_FOR_CPU(cpu) (TIMER10_OFFSET + (cpu) * 8)
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+
+struct tegra210_clockevent {
+   struct clock_event_device evt;
+   char name[20];
+   void __iomem *reg_base;
+};
+#define to_tegra_cevt(p) (container_of(p, struct tegra210_clockevent, evt))
+
+static struct tegra210_clockevent __percpu *tegra210_evt;
+
+static int tegra210_timer_set_next_event(unsigned long cycles,
+struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  tevt->reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static inline void timer_shutdown(struct tegra210_clockevent *tevt)
+{
+   writel(0, tevt->reg_base + TIMER_PTV);
+}
+
+static int tegra210_timer_shutdown(struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   timer_shutdown(tevt);
+
+   return 0;
+}
+
+static int tegra210_timer_set_periodic(struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   writel(TIMER_PTV_EN | TIMER_PTV_PER | ((tegra210_timer_freq / HZ) - 1),
+  tevt->reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static irqreturn_t tegra210_timer_isr(int irq, void *dev_id)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = dev_id;
+   writel(TIMER_PCR_INTR_CLR, tevt->reg_base + TIMER_PCR);
+   tevt->evt.event_handler(>evt);
+
+   return IRQ_HANDLED;
+}
+
+static int tegra210_timer_setup(unsigned int cpu)
+{
+   struct tegra210_clockevent *tevt = per_cpu_ptr(tegra210_evt, cpu);
+
+   irq_force_affinity(tevt->evt.irq, cpumask_of(cpu));
+   enable_irq(tevt->evt.irq);
+
+   clockevents_config_and_register(>evt, tegra210_timer_freq,
+   1, /* min */
+   0x1fff); /* 29 bits */
+
+   return 0;
+}
+
+static int tegra210_timer_stop(unsigned int cpu)
+{
+   struct

[PATCH V2 1/6] dt-bindings: timer: add Tegra210 timer

2019-01-28 Thread Joseph Lo
The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: Joseph Lo 
Reviewed-by: Rob Herring 
---
v2:
 * list all the interrupts that are supported by tegra210 timers block
 * add RB tag from Rob.
---
 .../bindings/timer/nvidia,tegra210-timer.txt  | 36 +++
 1 file changed, 36 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt 
b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index ..032cda96fe0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,36 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 14 interrupts; one per each timer channels 0 through
+  13.
+- clocks : Must contain one entry, for the module clock.
+  See ../clocks/clock-bindings.txt for details.
+
+timer@60005000 {
+   compatible = "nvidia,tegra210-timer";
+   reg = <0x0 0x60005000 0x0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = <_car TEGRA210_CLK_TIMER>;
+   clock-names = "timer";
+};
-- 
2.20.1



Re: [PATCH V2 2/6] clocksource: tegra: add Tegra210 timer driver

2019-01-28 Thread Joseph Lo

Hi Daniel,

Thanks for your review.

On 1/28/19 9:00 PM, Daniel Lezcano wrote:

On 28/01/2019 10:18, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Based on the work of Antti P Miettinen 

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
---
v2:
  * add error clean-up code
---
  drivers/clocksource/Kconfig  |   3 +
  drivers/clocksource/Makefile |   1 +
  drivers/clocksource/timer-tegra210.c | 268 +++
  include/linux/cpuhotplug.h   |   1 +
  4 files changed, 273 insertions(+)
  create mode 100644 drivers/clocksource/timer-tegra210.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..e6e3e64b6320 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -135,6 +135,9 @@ config TEGRA_TIMER
help
  Enables support for the Tegra driver.
  
+config TEGRA210_TIMER

+   def_bool ARCH_TEGRA_210_SOC
+


Please make the option consistent with the option below (VT8500_TIMER or
similar).


Okay, will check.




  config VT8500_TIMER
bool "VT8500 timer driver" if COMPILE_TEST
depends on HAS_IOMEM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cdd210ff89ea..95de59c8a47b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o
  obj-$(CONFIG_SUN5I_HSTIMER)   += timer-sun5i.o
  obj-$(CONFIG_MESON6_TIMER)+= timer-meson6.o
  obj-$(CONFIG_TEGRA_TIMER) += timer-tegra20.o
+obj-$(CONFIG_TEGRA210_TIMER)   += timer-tegra210.o
  obj-$(CONFIG_VT8500_TIMER)+= timer-vt8500.o
  obj-$(CONFIG_NSPIRE_TIMER)+= timer-zevio.o
  obj-$(CONFIG_BCM_KONA_TIMER)  += bcm_kona_timer.o
diff --git a/drivers/clocksource/timer-tegra210.c 
b/drivers/clocksource/timer-tegra210.c
new file mode 100644
index ..477b164e540b
--- /dev/null
+++ b/drivers/clocksource/timer-tegra210.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2019, NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static u32 tegra210_timer_freq;
+static void __iomem *tegra210_timer_reg_base;
+static u32 usec_config;
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+#define TIMERUS_CNTR_1US   0x10
+#define TIMERUS_USEC_CFG   0x14
+
+#define TIMER10_OFFSET 0x90
+#define TIMER10_IRQ_IDX10
+
+#define TIMER_FOR_CPU(cpu) (TIMER10_OFFSET + (cpu) * 8)
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+
+struct tegra210_clockevent {
+   struct clock_event_device evt;
+   char name[20];
+   void __iomem *reg_base;
+};
+#define to_tegra_cevt(p) (container_of(p, struct tegra210_clockevent, evt))
+
+static struct tegra210_clockevent __percpu *tegra210_evt;
+
+static int tegra210_timer_set_next_event(unsigned long cycles,
+struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  tevt->reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static inline void timer_shutdown(struct tegra210_clockevent *tevt)
+{
+   writel(0, tevt->reg_base + TIMER_PTV);
+}
+
+static int tegra210_timer_shutdown(struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   timer_shutdown(tevt);
+
+   return 0;
+}
+
+static int tegra210_timer_set_periodic(struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   writel(TIMER_PTV_EN | TIMER_PTV_PER | ((tegra210_timer_freq / HZ) - 1),
+  tevt->reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static irqreturn_t tegra210_timer_isr(int irq, void *dev_id)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = dev_id;
+   writel(TIMER_PCR_INTR_CLR, tevt->reg_base + TIMER_PCR);
+   tevt->evt.event_handler(>evt);
+
+   return IRQ_HANDLED;
+}
+
+static int tegra210_timer_setup(unsigned int cpu)
+{
+   struct tegra210_clockevent *tevt = per_cpu_ptr(tegra210_evt, cpu);
+
+   irq_force_affinity(tevt->evt.irq, cpumask_of(cpu));
+   enable_irq(tevt->evt.irq);
+
+   clockevents_config_a

Re: [PATCH V2 2/6] clocksource: tegra: add Tegra210 timer driver

2019-01-28 Thread Joseph Lo

On 1/28/19 11:09 PM, Thierry Reding wrote:

On Mon, Jan 28, 2019 at 05:18:11PM +0800, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Based on the work of Antti P Miettinen 

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
---
v2:
  * add error clean-up code
---
  drivers/clocksource/Kconfig  |   3 +
  drivers/clocksource/Makefile |   1 +
  drivers/clocksource/timer-tegra210.c | 268 +++
  include/linux/cpuhotplug.h   |   1 +
  4 files changed, 273 insertions(+)
  create mode 100644 drivers/clocksource/timer-tegra210.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..e6e3e64b6320 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -135,6 +135,9 @@ config TEGRA_TIMER
help
  Enables support for the Tegra driver.
  
+config TEGRA210_TIMER

+   def_bool ARCH_TEGRA_210_SOC
+
  config VT8500_TIMER
bool "VT8500 timer driver" if COMPILE_TEST
depends on HAS_IOMEM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cdd210ff89ea..95de59c8a47b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o
  obj-$(CONFIG_SUN5I_HSTIMER)   += timer-sun5i.o
  obj-$(CONFIG_MESON6_TIMER)+= timer-meson6.o
  obj-$(CONFIG_TEGRA_TIMER) += timer-tegra20.o
+obj-$(CONFIG_TEGRA210_TIMER)   += timer-tegra210.o
  obj-$(CONFIG_VT8500_TIMER)+= timer-vt8500.o
  obj-$(CONFIG_NSPIRE_TIMER)+= timer-zevio.o
  obj-$(CONFIG_BCM_KONA_TIMER)  += bcm_kona_timer.o
diff --git a/drivers/clocksource/timer-tegra210.c 
b/drivers/clocksource/timer-tegra210.c
new file mode 100644
index ..477b164e540b
--- /dev/null
+++ b/drivers/clocksource/timer-tegra210.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2019, NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static u32 tegra210_timer_freq;
+static void __iomem *tegra210_timer_reg_base;
+static u32 usec_config;
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+#define TIMERUS_CNTR_1US   0x10
+#define TIMERUS_USEC_CFG   0x14
+
+#define TIMER10_OFFSET 0x90
+#define TIMER10_IRQ_IDX10
+
+#define TIMER_FOR_CPU(cpu) (TIMER10_OFFSET + (cpu) * 8)
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+
+struct tegra210_clockevent {
+   struct clock_event_device evt;
+   char name[20];
+   void __iomem *reg_base;
+};
+#define to_tegra_cevt(p) (container_of(p, struct tegra210_clockevent, evt))
+
+static struct tegra210_clockevent __percpu *tegra210_evt;
+
+static int tegra210_timer_set_next_event(unsigned long cycles,
+struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  tevt->reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static inline void timer_shutdown(struct tegra210_clockevent *tevt)
+{
+   writel(0, tevt->reg_base + TIMER_PTV);
+}
+
+static int tegra210_timer_shutdown(struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   timer_shutdown(tevt);
+
+   return 0;
+}
+
+static int tegra210_timer_set_periodic(struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   writel(TIMER_PTV_EN | TIMER_PTV_PER | ((tegra210_timer_freq / HZ) - 1),
+  tevt->reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static irqreturn_t tegra210_timer_isr(int irq, void *dev_id)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = dev_id;
+   writel(TIMER_PCR_INTR_CLR, tevt->reg_base + TIMER_PCR);
+   tevt->evt.event_handler(>evt);
+
+   return IRQ_HANDLED;
+}


Up to here this is a duplicate of timer-tegra20.c. And a lot of
tegra210_timer_init() is the same as tegra20_timer_init() as well. Can't
we unify the two drivers instead?


I still prefer to remove the timer-tegra20 driver, because it didn't 
been used for Tegra 32 bit chips for quite a long time. So currently it 
just compiles OK, I also doubt the functionality still can achieve the 
same what 

[PATCH V3 2/6] clocksource: tegra: add Tegra210 timer driver

2019-01-29 Thread Joseph Lo
Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Based on the work of Antti P Miettinen 

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
---
v3:
 * use timer-of API
v2:
 * add error clean-up code
---
 drivers/clocksource/Kconfig  |   8 +
 drivers/clocksource/Makefile |   1 +
 drivers/clocksource/timer-tegra210.c | 246 +++
 include/linux/cpuhotplug.h   |   1 +
 4 files changed, 256 insertions(+)
 create mode 100644 drivers/clocksource/timer-tegra210.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..059b1b3f2adb 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -135,6 +135,14 @@ config TEGRA_TIMER
help
  Enables support for the Tegra driver.
 
+config TEGRA210_TIMER
+   bool "Tegra210 timer driver"
+   default y if ARCH_TEGRA_210_SOC
+   depends on ARCH_TEGRA_210_SOC
+   select TIMER_OF
+   help
+ Enable support for the Tegra210 driver.
+
 config VT8500_TIMER
bool "VT8500 timer driver" if COMPILE_TEST
depends on HAS_IOMEM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cdd210ff89ea..95de59c8a47b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o
 obj-$(CONFIG_SUN5I_HSTIMER)+= timer-sun5i.o
 obj-$(CONFIG_MESON6_TIMER) += timer-meson6.o
 obj-$(CONFIG_TEGRA_TIMER)  += timer-tegra20.o
+obj-$(CONFIG_TEGRA210_TIMER)   += timer-tegra210.o
 obj-$(CONFIG_VT8500_TIMER) += timer-vt8500.o
 obj-$(CONFIG_NSPIRE_TIMER) += timer-zevio.o
 obj-$(CONFIG_BCM_KONA_TIMER)   += bcm_kona_timer.o
diff --git a/drivers/clocksource/timer-tegra210.c 
b/drivers/clocksource/timer-tegra210.c
new file mode 100644
index ..7bc751c7da99
--- /dev/null
+++ b/drivers/clocksource/timer-tegra210.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2019, NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "timer-of.h"
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+#define TIMERUS_CNTR_1US   0x10
+#define TIMERUS_USEC_CFG   0x14
+
+#define TIMER10_OFFSET 0x90
+#define TIMER10_IRQ_IDX10
+
+#define TIMER_FOR_CPU(cpu) (TIMER10_OFFSET + (cpu) * 8)
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+#define get_cpu_timer_reg_base(evt)\
+({ \
+   struct timer_of *to = to_timer_of(evt); \
+   timer_of_base(to) + TIMER_FOR_CPU(smp_processor_id());  \
+})
+
+static u32 usec_config;
+
+static int tegra210_timer_set_next_event(unsigned long cycles,
+struct clock_event_device *evt)
+{
+   void __iomem *reg_base = get_cpu_timer_reg_base(evt);
+
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static int tegra210_timer_shutdown(struct clock_event_device *evt)
+{
+   void __iomem *reg_base = get_cpu_timer_reg_base(evt);
+
+   writel(0, reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static int tegra210_timer_set_periodic(struct clock_event_device *evt)
+{
+   void __iomem *reg_base = get_cpu_timer_reg_base(evt);
+
+   writel(TIMER_PTV_EN | TIMER_PTV_PER |
+  ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+  reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static irqreturn_t tegra210_timer_isr(int irq, void *dev_id)
+{
+   struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+   void __iomem *reg_base = get_cpu_timer_reg_base(evt);
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+   evt->event_handler(evt);
+
+   return IRQ_HANDLED;
+}
+
+static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
+   .flags = TIMER_OF_CLOCK | TIMER_OF_BASE,
+   .clkevt = {
+   .name = "tegra_timer",
+   .rating = 460,
+   .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+   .set_next_event = tegra210_timer_set_next_event,
+   .set_state_shutdown = tegra210_timer_shutdown,
+   .se

[PATCH V3 1/6] dt-bindings: timer: add Tegra210 timer

2019-01-29 Thread Joseph Lo
The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: Joseph Lo 
Reviewed-by: Rob Herring 
---
v3:
 * no change
v2:
 * list all the interrupts that are supported by tegra210 timers block
 * add RB tag from Rob.
---
 .../bindings/timer/nvidia,tegra210-timer.txt  | 36 +++
 1 file changed, 36 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt 
b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index ..032cda96fe0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,36 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 14 interrupts; one per each timer channels 0 through
+  13.
+- clocks : Must contain one entry, for the module clock.
+  See ../clocks/clock-bindings.txt for details.
+
+timer@60005000 {
+   compatible = "nvidia,tegra210-timer";
+   reg = <0x0 0x60005000 0x0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = <_car TEGRA210_CLK_TIMER>;
+   clock-names = "timer";
+};
-- 
2.20.1



Re: [PATCH V2 2/6] clocksource: tegra: add Tegra210 timer driver

2019-01-29 Thread Joseph Lo

On 1/29/19 6:29 PM, Thierry Reding wrote:

On Tue, Jan 29, 2019 at 10:41:55AM +0200, Peter De Schrijver wrote:

On Mon, Jan 28, 2019 at 04:09:08PM +0100, Thierry Reding wrote:

...



Up to here this is a duplicate of timer-tegra20.c. And a lot of
tegra210_timer_init() is the same as tegra20_timer_init() as well. Can't
we unify the two drivers instead?

The power cycle restrictions of the architected timer, do they not apply
to chips earlier than Tegra210 either? So don't we need all of these
additional features on the timer-tegra20.c driver as well? If so that


No. Chips prior to Tegra114 do not have an arch timer and the arch timer
does work correctly on Cortex-A15 so Tegra114 and Tegra124 can use it.
It's broken on Cortex-A57 though, so we can't use it as a wakeup source
on Tegra210.


If chips prior to Tegra114 don't have an architected timer, then we
can't remove the timer-tegra20 driver, because we still need it on
Tegra20 and Tegra30, right?



For Tegra20/30, it's Cortext-A9 with TWD timer. (arch/arm/kernel/smp_twd.c)

Originally, I thought the functionality of timer-tegra20 would be fully 
replaced by TWD timer driver. But from the log in the kernelci test 
farm[1][2], it looks to me the timer-tegra20 driver still works as 
clocksource driver for Tegra20/30. I cannot confirm if the clock event 
device has been replaced by TWD timer in the log. It could be replaced 
in the background. And by looking into the driver, it should be.


Compare to the log of Tegra124[3], it has been fully replaced by arch 
timer driver.


Note, "timer_us" is the name of Tegra20 timer.
[1]: 
https://storage.kernelci.org/mainline/master/v5.0-rc4-1-g4aa9fc2a435a/arm/tegra_defconfig/lab-baylibre-seattle/boot-tegra30-beaver.html
[2]: 
https://storage.kernelci.org/stable-rc/linux-4.9.y/v4.9.153-43-g6674590d15d2/arm/tegra_defconfig/lab-baylibre-seattle/boot-tegra20-iris-512.html
[3]: 
https://storage.kernelci.org/lsk/linux-linaro-lsk-v4.9/lsk-v4.9-18.09-1494-gde3059d32f93/arm/tegra_defconfig/lab-collabora/boot-tegra124-nyan-big.html


Thanks,
Joseph


[PATCH V4 1/7] dt-bindings: timer: add Tegra210 timer

2019-01-31 Thread Joseph Lo
The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: Joseph Lo 
Reviewed-by: Rob Herring 
---
V4:
 * no change
v3:
 * no change
v2:
 * list all the interrupts that are supported by tegra210 timers block
 * add RB tag from Rob.
---
 .../bindings/timer/nvidia,tegra210-timer.txt  | 36 +++
 1 file changed, 36 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt 
b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index ..032cda96fe0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,36 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 14 interrupts; one per each timer channels 0 through
+  13.
+- clocks : Must contain one entry, for the module clock.
+  See ../clocks/clock-bindings.txt for details.
+
+timer@60005000 {
+   compatible = "nvidia,tegra210-timer";
+   reg = <0x0 0x60005000 0x0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = <_car TEGRA210_CLK_TIMER>;
+   clock-names = "timer";
+};
-- 
2.20.1



[PATCH V4 2/7] clocksource: tegra: add Tegra210 timer support

2019-01-31 Thread Joseph Lo
Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
---
v4:
 * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
 * use timer-of API
v2:
 * add error clean-up code
---
 drivers/clocksource/Kconfig |   2 +-
 drivers/clocksource/timer-tegra20.c | 369 
 include/linux/cpuhotplug.h  |   1 +
 3 files changed, 272 insertions(+), 100 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..6af78534a285 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,7 @@ config SUN5I_HSTIMER
 config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM
+   select TIMER_OF
help
  Enables support for the Tegra driver.
 
diff --git a/drivers/clocksource/timer-tegra20.c 
b/drivers/clocksource/timer-tegra20.c
index 4293943f4e2b..96a809341c9b 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
  *
  */
 
-#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
-#include 
-#include 
+#include 
+#include 
+#include 
+
+#include "timer-of.h"
 
+#ifdef CONFIG_ARM
 #include 
+#endif
 
 #define RTC_SECONDS0x08
 #define RTC_SHADOW_SECONDS 0x0c
@@ -43,70 +46,147 @@
 #define TIMER2_BASE 0x8
 #define TIMER3_BASE 0x50
 #define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER10_BASE 0x90
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_BASE TIMER3_BASE
+#else
+#define TIMER_BASE TIMER10_BASE
+#endif
+#define TIMER10_IRQ_IDX10
+#define TIMER_FOR_CPU(cpu) (TIMER_BASE + (cpu) * 8)
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+
+static u32 usec_config;
 static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
 static void __iomem *rtc_base;
-
 static struct timespec64 persistent_ts;
 static u64 persistent_ms, last_persistent_ms;
-
 static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-   writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-   readl_relaxed(timer_reg_base + (reg))
+#endif
 
 static int tegra_timer_set_next_event(unsigned long cycles,
 struct clock_event_device *evt)
 {
-   u32 reg;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
 
-   reg = 0x8000 | ((cycles > 1) ? (cycles-1) : 0);
-   timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  reg_base + TIMER_PTV);
 
return 0;
 }
 
-static inline void timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_shutdown(struct clock_event_device *evt)
 {
-   timer_writel(0, TIMER3_BASE + TIMER_PTV);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(0, reg_base + TIMER_PTV);
+
+   return 0;
 }
 
-static int tegra_timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_set_periodic(struct clock_event_device *evt)
 {
-   timer_shutdown(evt);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PTV_EN | TIMER_PTV_PER |
+  ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+  reg_base + TIMER_PTV);
+
return 0;
 }
 
-static int tegra_timer_set_periodic(struct clock_event_device *evt)
+static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
 {
-   u32 reg = 0xC000 | ((100 / HZ) - 1);
+   struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+   evt->event_handler(evt);
+
+   return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_ARM64
+static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
+   .flags = TIMER_OF_CLOCK | TIMER_OF_BASE,
+
+   .clkevt = {
+   .name = "tegra_timer",
+   .rating = 460,
+   .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+   .set_next_event = tegra_timer_set_next_eve

Re: [PATCH 1/6] dt-bindings: timer: add Tegra210 timer

2019-01-24 Thread Joseph Lo

Hi Jon,

Thanks for reviewing.

On 1/24/19 6:30 PM, Jon Hunter wrote:


On 07/01/2019 03:28, Joseph Lo wrote:

The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: Joseph Lo 
---
  .../bindings/timer/nvidia,tegra210-timer.txt  | 25 +++
  1 file changed, 25 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt 
b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index ..ba511220a669
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,25 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 4 interrupts; one per each of TMR10 through TMR13.


Why do we only add the interrupts for TMR10 - TMR13? What about the others?



The others (TMR0-TMR9) are occupied for other usages. TMR5 is occupied 
for the watchdog timer in the upstream kernel. And others (still in 
TMR0-TMR9) are occupied for different usages in our downstream kernel.


And notice that only TMR10-TMR13 are running at the oscillator clock 
(clk_m). With the Tegra210 timer driver, we introduce in this series, 
which only replace the clock event device function that was originally 
owned by the arch timer (armv8 timer) and it also running at the 
oscillator clock. The sched_timer still owns by the arch timer. So the 
timer resolution will be the same. That's why we choose TMR10-TMR13 as 
the timer for Tegra210.


Thanks,
Joseph


Re: [PATCH 2/6] clocksource: tegra: add Tegra210 timer driver

2019-01-24 Thread Joseph Lo

On 1/24/19 7:09 PM, Jon Hunter wrote:


On 07/01/2019 03:28, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Based on the work of Antti P Miettinen 

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
---
  drivers/clocksource/Kconfig  |   3 +
  drivers/clocksource/Makefile |   1 +
  drivers/clocksource/timer-tegra210.c | 240 +++
  include/linux/cpuhotplug.h   |   1 +
  4 files changed, 245 insertions(+)
  create mode 100644 drivers/clocksource/timer-tegra210.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..e6e3e64b6320 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -135,6 +135,9 @@ config TEGRA_TIMER
help
  Enables support for the Tegra driver.
  
+config TEGRA210_TIMER

+   def_bool ARCH_TEGRA_210_SOC
+
  config VT8500_TIMER
bool "VT8500 timer driver" if COMPILE_TEST
depends on HAS_IOMEM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cdd210ff89ea..95de59c8a47b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o
  obj-$(CONFIG_SUN5I_HSTIMER)   += timer-sun5i.o
  obj-$(CONFIG_MESON6_TIMER)+= timer-meson6.o
  obj-$(CONFIG_TEGRA_TIMER) += timer-tegra20.o
+obj-$(CONFIG_TEGRA210_TIMER)   += timer-tegra210.o
  obj-$(CONFIG_VT8500_TIMER)+= timer-vt8500.o
  obj-$(CONFIG_NSPIRE_TIMER)+= timer-zevio.o
  obj-$(CONFIG_BCM_KONA_TIMER)  += bcm_kona_timer.o
diff --git a/drivers/clocksource/timer-tegra210.c 
b/drivers/clocksource/timer-tegra210.c
new file mode 100644
index ..d88c127d3b3b
--- /dev/null
+++ b/drivers/clocksource/timer-tegra210.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2019, NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static u32 tegra210_timer_freq;
+static void __iomem *tegra210_timer_reg_base;
+static u32 usec_config;
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+#define TIMERUS_CNTR_1US   0x10
+#define TIMERUS_USEC_CFG   0x14
+
+#define TIMER10_OFFSET 0x90
+
+#define TIMER_FOR_CPU(cpu) (TIMER10_OFFSET + (cpu) * 8)
+
+struct tegra210_clockevent {
+   struct clock_event_device evt;
+   char name[20];
+   void __iomem *reg_base;
+};
+#define to_tegra_cevt(p) (container_of(p, struct tegra210_clockevent, evt))
+
+static struct tegra210_clockevent __percpu *tegra210_evt;
+
+static int tegra210_timer_set_next_event(unsigned long cycles,
+struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  tevt->reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static inline void timer_shutdown(struct tegra210_clockevent *tevt)
+{
+   writel(0, tevt->reg_base + TIMER_PTV);
+}
+
+static int tegra210_timer_shutdown(struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   timer_shutdown(tevt);
+
+   return 0;
+}
+
+static int tegra210_timer_set_periodic(struct clock_event_device *evt)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = to_tegra_cevt(evt);
+   writel(TIMER_PTV_EN | TIMER_PTV_PER | ((tegra210_timer_freq / HZ) - 1),
+  tevt->reg_base + TIMER_PTV);
+
+   return 0;
+}
+
+static irqreturn_t tegra210_timer_isr(int irq, void *dev_id)
+{
+   struct tegra210_clockevent *tevt;
+
+   tevt = dev_id;
+   writel(TIMER_PCR_INTR_CLR, tevt->reg_base + TIMER_PCR);
+   tevt->evt.event_handler(>evt);
+
+   return IRQ_HANDLED;
+}
+
+static int tegra210_timer_setup(unsigned int cpu)
+{
+   struct tegra210_clockevent *tevt = per_cpu_ptr(tegra210_evt, cpu);
+
+   irq_force_affinity(tevt->evt.irq, cpumask_of(cpu));
+   enable_irq(tevt->evt.irq);
+
+   clockevents_config_and_register(>evt, tegra210_timer_freq,
+   1, /* min */
+   0x1fff); /* 29 bits */
+
+   return 0;
+}
+
+static int tegra210_timer_stop(unsigned int cpu)
+{
+   struct tegra210_clockevent *tevt = per_cp

Re: [PATCH V6 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-08 Thread Joseph Lo

Hi Daniel & Thomas,

Do we have the chance to get this patch merged for K5.1?

Thanks,
Joseph

On 2/2/19 12:16 AM, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
Acked-by: Jon Hunter 
---
v6:
  * refine the timer defines
  * add ack tag from Jon.
v5:
  * add ack tag from Thierry
v4:
  * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
  * use timer-of API
v2:
  * add error clean-up code
---
  drivers/clocksource/Kconfig |   2 +-
  drivers/clocksource/timer-tegra20.c | 371 
  include/linux/cpuhotplug.h  |   1 +
  3 files changed, 270 insertions(+), 104 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..6af78534a285 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,7 @@ config SUN5I_HSTIMER
  config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM
+   select TIMER_OF
help
  Enables support for the Tegra driver.
  
diff --git a/drivers/clocksource/timer-tegra20.c b/drivers/clocksource/timer-tegra20.c

index 4293943f4e2b..f66edd63d7f4 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
   *
   */
  
-#include 

+#include 
+#include 
+#include 
+#include 
+#include 
  #include 
-#include 
  #include 
-#include 
-#include 
-#include 
-#include 
-#include 
  #include 
  #include 
-#include 
-#include 
+#include 
+#include 
+#include 
+
+#include "timer-of.h"
  
+#ifdef CONFIG_ARM

  #include 
+#endif
  
  #define RTC_SECONDS0x08

  #define RTC_SHADOW_SECONDS 0x0c
@@ -39,74 +42,145 @@
  #define TIMERUS_USEC_CFG 0x14
  #define TIMERUS_CNTR_FREEZE 0x4c
  
-#define TIMER1_BASE 0x0

-#define TIMER2_BASE 0x8
-#define TIMER3_BASE 0x50
-#define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_CPU0 0x50 /* TIMER3 */
+#else
+#define TIMER_CPU0 0x90 /* TIMER10 */
+#define TIMER10_IRQ_IDX10
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+#endif
+#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)
+
+static u32 usec_config;
  static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
  static void __iomem *rtc_base;
-
  static struct timespec64 persistent_ts;
  static u64 persistent_ms, last_persistent_ms;
-
  static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-   writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-   readl_relaxed(timer_reg_base + (reg))
+#endif
  
  static int tegra_timer_set_next_event(unsigned long cycles,

 struct clock_event_device *evt)
  {
-   u32 reg;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
  
-	reg = 0x8000 | ((cycles > 1) ? (cycles-1) : 0);

-   timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  reg_base + TIMER_PTV);
  
  	return 0;

  }
  
-static inline void timer_shutdown(struct clock_event_device *evt)

+static int tegra_timer_shutdown(struct clock_event_device *evt)
  {
-   timer_writel(0, TIMER3_BASE + TIMER_PTV);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(0, reg_base + TIMER_PTV);
+
+   return 0;
  }
  
-static int tegra_timer_shutdown(struct clock_event_device *evt)

+static int tegra_timer_set_periodic(struct clock_event_device *evt)
  {
-   timer_shutdown(evt);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PTV_EN | TIMER_PTV_PER |
+  ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+  reg_base + TIMER_PTV);
+
return 0;
  }
  
-static int tegra_timer_set_periodic(struct clock_event_device *evt)

+static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
  {
-   u32 reg = 0xC000 | ((100 / HZ) - 1);
+   struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);

[PATCH] clocksource/drivers/tegra: rework for compensation of suspend time

2019-04-01 Thread Joseph Lo
Since the clocksource framework has the support for suspend time
compensation. Re-work the driver to use that, so we can reduce the
duplicate code.

Suggested-by: Daniel Lezcano 
Signed-off-by: Joseph Lo 
---
 drivers/clocksource/timer-tegra20.c | 63 +
 1 file changed, 20 insertions(+), 43 deletions(-)

diff --git a/drivers/clocksource/timer-tegra20.c 
b/drivers/clocksource/timer-tegra20.c
index fdb3d795a409..919b3568c495 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -60,9 +60,6 @@
 static u32 usec_config;
 static void __iomem *timer_reg_base;
 #ifdef CONFIG_ARM
-static void __iomem *rtc_base;
-static struct timespec64 persistent_ts;
-static u64 persistent_ms, last_persistent_ms;
 static struct delay_timer tegra_delay_timer;
 #endif
 
@@ -199,40 +196,30 @@ static unsigned long 
tegra_delay_timer_read_counter_long(void)
return readl(timer_reg_base + TIMERUS_CNTR_1US);
 }
 
+static struct timer_of suspend_rtc_to = {
+   .flags = TIMER_OF_BASE | TIMER_OF_CLOCK,
+};
+
 /*
  * tegra_rtc_read - Reads the Tegra RTC registers
  * Care must be taken that this funciton is not called while the
  * tegra_rtc driver could be executing to avoid race conditions
  * on the RTC shadow register
  */
-static u64 tegra_rtc_read_ms(void)
+static u64 tegra_rtc_read_ms(struct clocksource *cs)
 {
-   u32 ms = readl(rtc_base + RTC_MILLISECONDS);
-   u32 s = readl(rtc_base + RTC_SHADOW_SECONDS);
+   u32 ms = readl(timer_of_base(_rtc_to) + RTC_MILLISECONDS);
+   u32 s = readl(timer_of_base(_rtc_to) + RTC_SHADOW_SECONDS);
return (u64)s * MSEC_PER_SEC + ms;
 }
 
-/*
- * tegra_read_persistent_clock64 -  Return time from a persistent clock.
- *
- * Reads the time from a source which isn't disabled during PM, the
- * 32k sync timer.  Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec64.
- * Care must be taken that this funciton is not called while the
- * tegra_rtc driver could be executing to avoid race conditions
- * on the RTC shadow register
- */
-static void tegra_read_persistent_clock64(struct timespec64 *ts)
-{
-   u64 delta;
-
-   last_persistent_ms = persistent_ms;
-   persistent_ms = tegra_rtc_read_ms();
-   delta = persistent_ms - last_persistent_ms;
-
-   timespec64_add_ns(_ts, delta * NSEC_PER_MSEC);
-   *ts = persistent_ts;
-}
+static struct clocksource suspend_rtc_clocksource = {
+   .name   = "tegra_suspend_timer",
+   .rating = 200,
+   .read   = tegra_rtc_read_ms,
+   .mask   = CLOCKSOURCE_MASK(32),
+   .flags  = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
+};
 #endif
 
 static int tegra_timer_common_init(struct device_node *np, struct timer_of *to)
@@ -385,25 +372,15 @@ static int __init tegra_init_timer(struct device_node *np)
 
 static int __init tegra20_init_rtc(struct device_node *np)
 {
-   struct clk *clk;
+   int ret;
 
-   rtc_base = of_iomap(np, 0);
-   if (!rtc_base) {
-   pr_err("Can't map RTC registers\n");
-   return -ENXIO;
-   }
+   ret = timer_of_init(np, _rtc_to);
+   if (ret)
+   return ret;
 
-   /*
-* rtc registers are used by read_persistent_clock, keep the rtc clock
-* enabled
-*/
-   clk = of_clk_get(np, 0);
-   if (IS_ERR(clk))
-   pr_warn("Unable to get rtc-tegra clock\n");
-   else
-   clk_prepare_enable(clk);
+   clocksource_register_hz(_rtc_clocksource, 1000);
 
-   return register_persistent_clock(tegra_read_persistent_clock64);
+   return 0;
 }
 TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
 #endif
-- 
2.21.0



Re: [PATCH] clocksource/drivers/tegra: rework for compensation of suspend time

2019-04-02 Thread Joseph Lo

On 4/2/19 10:46 PM, Thierry Reding wrote:

On Tue, Apr 02, 2019 at 11:02:34AM +0800, Joseph Lo wrote:

Since the clocksource framework has the support for suspend time
compensation. Re-work the driver to use that, so we can reduce the
duplicate code.

Suggested-by: Daniel Lezcano 
Signed-off-by: Joseph Lo 
---
  drivers/clocksource/timer-tegra20.c | 63 +
  1 file changed, 20 insertions(+), 43 deletions(-)


Nice!



diff --git a/drivers/clocksource/timer-tegra20.c 
b/drivers/clocksource/timer-tegra20.c
index fdb3d795a409..919b3568c495 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -60,9 +60,6 @@
  static u32 usec_config;
  static void __iomem *timer_reg_base;
  #ifdef CONFIG_ARM
-static void __iomem *rtc_base;
-static struct timespec64 persistent_ts;
-static u64 persistent_ms, last_persistent_ms;
  static struct delay_timer tegra_delay_timer;
  #endif
  
@@ -199,40 +196,30 @@ static unsigned long tegra_delay_timer_read_counter_long(void)

return readl(timer_reg_base + TIMERUS_CNTR_1US);
  }
  
+static struct timer_of suspend_rtc_to = {

+   .flags = TIMER_OF_BASE | TIMER_OF_CLOCK,
+};
+
  /*
   * tegra_rtc_read - Reads the Tegra RTC registers
   * Care must be taken that this funciton is not called while the
   * tegra_rtc driver could be executing to avoid race conditions
   * on the RTC shadow register
   */
-static u64 tegra_rtc_read_ms(void)
+static u64 tegra_rtc_read_ms(struct clocksource *cs)
  {
-   u32 ms = readl(rtc_base + RTC_MILLISECONDS);
-   u32 s = readl(rtc_base + RTC_SHADOW_SECONDS);
+   u32 ms = readl(timer_of_base(_rtc_to) + RTC_MILLISECONDS);
+   u32 s = readl(timer_of_base(_rtc_to) + RTC_SHADOW_SECONDS);
return (u64)s * MSEC_PER_SEC + ms;
  }
  
-/*

- * tegra_read_persistent_clock64 -  Return time from a persistent clock.
- *
- * Reads the time from a source which isn't disabled during PM, the
- * 32k sync timer.  Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec64.
- * Care must be taken that this funciton is not called while the
- * tegra_rtc driver could be executing to avoid race conditions
- * on the RTC shadow register
- */
-static void tegra_read_persistent_clock64(struct timespec64 *ts)
-{
-   u64 delta;
-
-   last_persistent_ms = persistent_ms;
-   persistent_ms = tegra_rtc_read_ms();
-   delta = persistent_ms - last_persistent_ms;
-
-   timespec64_add_ns(_ts, delta * NSEC_PER_MSEC);
-   *ts = persistent_ts;
-}
+static struct clocksource suspend_rtc_clocksource = {
+   .name   = "tegra_suspend_timer",
+   .rating = 200,
+   .read   = tegra_rtc_read_ms,
+   .mask   = CLOCKSOURCE_MASK(32),
+   .flags  = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
+};
  #endif
  
  static int tegra_timer_common_init(struct device_node *np, struct timer_of *to)

@@ -385,25 +372,15 @@ static int __init tegra_init_timer(struct device_node *np)
  
  static int __init tegra20_init_rtc(struct device_node *np)

  {
-   struct clk *clk;
+   int ret;
  
-	rtc_base = of_iomap(np, 0);

-   if (!rtc_base) {
-   pr_err("Can't map RTC registers\n");
-   return -ENXIO;
-   }
+   ret = timer_of_init(np, _rtc_to);
+   if (ret)
+   return ret;
  
-	/*

-* rtc registers are used by read_persistent_clock, keep the rtc clock
-* enabled
-*/
-   clk = of_clk_get(np, 0);
-   if (IS_ERR(clk))
-   pr_warn("Unable to get rtc-tegra clock\n");
-   else
-   clk_prepare_enable(clk);
+   clocksource_register_hz(_rtc_clocksource, 1000);
  
-	return register_persistent_clock(tegra_read_persistent_clock64);

+   return 0;
  }
  TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
  #endif


I wonder if there's any reason left for the #ifdefs now. My recollection
is that these were only needed because register_persistent_clock() was
not available on 64-bit ARM. The new APIs seem to be available
regardless of architecture, so do we still need to differentiate?



Actually, only Tegra20/30 that doesn't have ARM arch timer support need 
this. The latter Tegra chips which have ARM arch timer support use TSC ( 
time stamp counter or timer system counter depends on the chip it has 
different name) as the timer source in the PMC. And it uses OSC during 
runtime and switches to 32KHz always-on clock source to keep counting 
when the chip is in the SC7 or LP0 state.


So I didn't change that for this reason.

Thanks,
Joseph



Re: [PATCH V6 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-19 Thread Joseph Lo

On 2/18/19 5:39 PM, Daniel Lezcano wrote:

On 18/02/2019 10:01, Joseph Lo wrote:

On 2/15/19 11:14 PM, Daniel Lezcano wrote:

On 01/02/2019 17:16, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a
wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
Acked-by: Jon Hunter 
---
v6:
   * refine the timer defines
   * add ack tag from Jon.
v5:
   * add ack tag from Thierry
v4:
   * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
   * use timer-of API
v2:
   * add error clean-up code
---

[snip]

+    for_each_possible_cpu(cpu) {
+    struct timer_of *cpu_to;
+
+    cpu_to = per_cpu_ptr(_to, cpu);
+    cpu_to->of_base.base = timer_reg_base +
TIMER_BASE_FOR_CPU(cpu);
+    cpu_to->of_clk.rate = timer_of_rate(to);
+    cpu_to->clkevt.cpumask = cpumask_of(cpu);
+
+    cpu_to->clkevt.irq =
+    irq_of_parse_and_map(np, IRQ_IDX_FOR_CPU(cpu));
+    if (!cpu_to->clkevt.irq) {
+    pr_err("%s: can't map IRQ for CPU%d\n",
+   __func__, cpu);
+    ret = -EINVAL;
+    goto out;
+    }
+
+    irq_set_status_flags(cpu_to->clkevt.irq, IRQ_NOAUTOEN);
+    ret = request_irq(cpu_to->clkevt.irq, tegra_timer_isr,
+  IRQF_TIMER | IRQF_NOBALANCING,
+  cpu_to->clkevt.name, _to->clkevt);
+    if (ret) {
+    pr_err("%s: cannot setup irq %d for CPU%d\n",
+    __func__, cpu_to->clkevt.irq, cpu);
+    ret = -EINVAL;
+    goto out_irq;
+    }
+    }


You should configure the timer in the tegra_timer_setup() function
instead of using this cpu loop.



I think I still need to leave 'irq_of_parse_and_map' and 'request_irq'
here. Is that ok?


Perhaps you can store the np pointer in the private data structure of
timer-of and let the timer_of API to retrieve the irq in the cpuhp
callbacks.

irq_of_parse_and_map will be called by timer-of.

I'm not sure irq_set_status_flags really operates on the irq because it
is called after request_irq.



I did some experiments today. The 'irq_of_parse_and_map', 'request_irq' 
and 'setup_irq' are not able to run in the atomic section that 
tegra_timer_setup would be triggered in.


So I think I still need to leave the IRQ configuration code here in the 
loop. Should I move others to 'tegra_timer_setup' or just keep as the 
same in this patch?


Thanks,
Joseph


[PATCH V7 2/8] clocksource: tegra: add Tegra210 timer support

2019-02-20 Thread Joseph Lo
Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
Acked-by: Jon Hunter 
---
v7:
 * kconfig fix for 'depends on ARM || ARM64'
 * move suspend/resume to clkevt
 * refine the usage for the macro of TIMER_OF_DECLARE
v6:
 * refine the timer defines
 * add ack tag from Jon.
v5:
 * add ack tag from Thierry
v4:
 * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
 * use timer-of API
v2:
 * add error clean-up code
---
 drivers/clocksource/Kconfig |   3 +-
 drivers/clocksource/timer-tegra20.c | 370 +++-
 include/linux/cpuhotplug.h  |   1 +
 3 files changed, 262 insertions(+), 112 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 8dfd3bc448d0..5d93e580e5dc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,8 @@ config SUN5I_HSTIMER
 config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM
+   select TIMER_OF
+   depends on ARM || ARM64
help
  Enables support for the Tegra driver.
 
diff --git a/drivers/clocksource/timer-tegra20.c 
b/drivers/clocksource/timer-tegra20.c
index 4293943f4e2b..fdb3d795a409 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
  *
  */
 
-#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
+#include 
 #include 
-#include 
+#include 
+
+#include "timer-of.h"
 
+#ifdef CONFIG_ARM
 #include 
+#endif
 
 #define RTC_SECONDS0x08
 #define RTC_SHADOW_SECONDS 0x0c
@@ -39,74 +42,161 @@
 #define TIMERUS_USEC_CFG 0x14
 #define TIMERUS_CNTR_FREEZE 0x4c
 
-#define TIMER1_BASE 0x0
-#define TIMER2_BASE 0x8
-#define TIMER3_BASE 0x50
-#define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_CPU0 0x50 /* TIMER3 */
+#else
+#define TIMER_CPU0 0x90 /* TIMER10 */
+#define TIMER10_IRQ_IDX10
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+#endif
+#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)
+
+static u32 usec_config;
 static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
 static void __iomem *rtc_base;
-
 static struct timespec64 persistent_ts;
 static u64 persistent_ms, last_persistent_ms;
-
 static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-   writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-   readl_relaxed(timer_reg_base + (reg))
+#endif
 
 static int tegra_timer_set_next_event(unsigned long cycles,
 struct clock_event_device *evt)
 {
-   u32 reg;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
 
-   reg = 0x8000 | ((cycles > 1) ? (cycles-1) : 0);
-   timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  reg_base + TIMER_PTV);
 
return 0;
 }
 
-static inline void timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_shutdown(struct clock_event_device *evt)
 {
-   timer_writel(0, TIMER3_BASE + TIMER_PTV);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(0, reg_base + TIMER_PTV);
+
+   return 0;
 }
 
-static int tegra_timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_set_periodic(struct clock_event_device *evt)
 {
-   timer_shutdown(evt);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PTV_EN | TIMER_PTV_PER |
+  ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+  reg_base + TIMER_PTV);
+
return 0;
 }
 
-static int tegra_timer_set_periodic(struct clock_event_device *evt)
+static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
+{
+   struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+   evt->event_handler(evt);
+
+   return IRQ_HANDLED;
+}
+
+static vo

[PATCH V7 1/8] dt-bindings: timer: add Tegra210 timer

2019-02-20 Thread Joseph Lo
The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: Joseph Lo 
Reviewed-by: Rob Herring 
Acked-by: Jon Hunter 
---
v7:
 * no change
v6:
 * add ack tag from Jon.
v5:
 * no change
v4:
 * no change
v3:
 * no change
v2:
 * list all the interrupts that are supported by tegra210 timers block
 * add RB tag from Rob.
---
 .../bindings/timer/nvidia,tegra210-timer.txt  | 36 +++
 1 file changed, 36 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt 
b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index ..032cda96fe0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,36 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 14 interrupts; one per each timer channels 0 through
+  13.
+- clocks : Must contain one entry, for the module clock.
+  See ../clocks/clock-bindings.txt for details.
+
+timer@60005000 {
+   compatible = "nvidia,tegra210-timer";
+   reg = <0x0 0x60005000 0x0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = <_car TEGRA210_CLK_TIMER>;
+   clock-names = "timer";
+};
-- 
2.20.1



Re: [PATCH V7 2/8] clocksource: tegra: add Tegra210 timer support

2019-02-22 Thread Joseph Lo




On 2/22/19 4:43 PM, Daniel Lezcano wrote:

On 21/02/2019 08:21, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
Acked-by: Jon Hunter 
---


Acked-by: Daniel Lezcano 


Hi Daniel,

Thanks for your review again. Regarding to Thierry's suggestion in [1], 
could you help to pick up patch 1~3 in this series in clocksource tree?


[1]: https://patchwork.ozlabs.org/patch/1034075/

If not, I'll let him know this series needs to go with Tegra tree.



Will you take care of dropping the persistent clocksource code in this
driver?


Yes, will do.

Thanks,
Joseph




v7:
  * kconfig fix for 'depends on ARM || ARM64'
  * move suspend/resume to clkevt
  * refine the usage for the macro of TIMER_OF_DECLARE
v6:
  * refine the timer defines
  * add ack tag from Jon.
v5:
  * add ack tag from Thierry
v4:
  * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
  * use timer-of API
v2:
  * add error clean-up code
---
  drivers/clocksource/Kconfig |   3 +-
  drivers/clocksource/timer-tegra20.c | 370 +++-
  include/linux/cpuhotplug.h  |   1 +
  3 files changed, 262 insertions(+), 112 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 8dfd3bc448d0..5d93e580e5dc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,8 @@ config SUN5I_HSTIMER
  config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM
+   select TIMER_OF
+   depends on ARM || ARM64
help
  Enables support for the Tegra driver.
  
diff --git a/drivers/clocksource/timer-tegra20.c b/drivers/clocksource/timer-tegra20.c

index 4293943f4e2b..fdb3d795a409 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
   *
   */
  
-#include 

+#include 
+#include 
+#include 
+#include 
+#include 
  #include 
-#include 
  #include 
-#include 
-#include 
-#include 
-#include 
-#include 
  #include 
  #include 
+#include 
  #include 
-#include 
+#include 
+
+#include "timer-of.h"
  
+#ifdef CONFIG_ARM

  #include 
+#endif
  
  #define RTC_SECONDS0x08

  #define RTC_SHADOW_SECONDS 0x0c
@@ -39,74 +42,161 @@
  #define TIMERUS_USEC_CFG 0x14
  #define TIMERUS_CNTR_FREEZE 0x4c
  
-#define TIMER1_BASE 0x0

-#define TIMER2_BASE 0x8
-#define TIMER3_BASE 0x50
-#define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_CPU0 0x50 /* TIMER3 */
+#else
+#define TIMER_CPU0 0x90 /* TIMER10 */
+#define TIMER10_IRQ_IDX10
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+#endif
+#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)
+
+static u32 usec_config;
  static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
  static void __iomem *rtc_base;
-
  static struct timespec64 persistent_ts;
  static u64 persistent_ms, last_persistent_ms;
-
  static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-   writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-   readl_relaxed(timer_reg_base + (reg))
+#endif
  
  static int tegra_timer_set_next_event(unsigned long cycles,

 struct clock_event_device *evt)
  {
-   u32 reg;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
  
-	reg = 0x8000 | ((cycles > 1) ? (cycles-1) : 0);

-   timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  reg_base + TIMER_PTV);
  
  	return 0;

  }
  
-static inline void timer_shutdown(struct clock_event_device *evt)

+static int tegra_timer_shutdown(struct clock_event_device *evt)
  {
-   timer_writel(0, TIMER3_BASE + TIMER_PTV);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(0, reg_base + TIMER_PTV);
+
+   return 0;
  }
  
-static int tegra_timer_shutdown(struct clock_event_device *evt)

+static int tegra_timer_set_periodic(struct clock_event_device *evt)
  {
-   timer_shutdown(evt);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TI

Re: [PATCH V6 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-13 Thread Joseph Lo

On 2/13/19 4:55 PM, Daniel Lezcano wrote:

On 08/02/2019 14:23, Joseph Lo wrote:

Hi Daniel & Thomas,

Do we have the chance to get this patch merged for K5.1?


Hi Jospeh,

sorry for the delay, I was overbooked these past two weeks.

Overall it looks ok but give me a couple of days to review the driver
more deeply.


No problem, thanks.





On 2/2/19 12:16 AM, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a
wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
Acked-by: Jon Hunter 
---
v6:
   * refine the timer defines
   * add ack tag from Jon.
v5:
   * add ack tag from Thierry
v4:
   * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
   * use timer-of API
v2:
   * add error clean-up code
---
   drivers/clocksource/Kconfig |   2 +-
   drivers/clocksource/timer-tegra20.c | 371 
   include/linux/cpuhotplug.h  |   1 +
   3 files changed, 270 insertions(+), 104 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..6af78534a285 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,7 @@ config SUN5I_HSTIMER
   config TEGRA_TIMER
   bool "Tegra timer driver" if COMPILE_TEST
   select CLKSRC_MMIO
-    depends on ARM
+    select TIMER_OF
   help
     Enables support for the Tegra driver.
   diff --git a/drivers/clocksource/timer-tegra20.c
b/drivers/clocksource/timer-tegra20.c
index 4293943f4e2b..f66edd63d7f4 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
    *
    */
   -#include 
+#include 
+#include 
+#include 
+#include 
+#include 
   #include 
-#include 
   #include 
-#include 
-#include 
-#include 
-#include 
-#include 
   #include 
   #include 
-#include 
-#include 
+#include 
+#include 
+#include 
+
+#include "timer-of.h"
   +#ifdef CONFIG_ARM
   #include 
+#endif
     #define RTC_SECONDS    0x08
   #define RTC_SHADOW_SECONDS 0x0c
@@ -39,74 +42,145 @@
   #define TIMERUS_USEC_CFG 0x14
   #define TIMERUS_CNTR_FREEZE 0x4c
   -#define TIMER1_BASE 0x0
-#define TIMER2_BASE 0x8
-#define TIMER3_BASE 0x50
-#define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER_PTV    0x0
+#define TIMER_PTV_EN    BIT(31)
+#define TIMER_PTV_PER    BIT(30)
+#define TIMER_PCR    0x4
+#define TIMER_PCR_INTR_CLR    BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_CPU0    0x50 /* TIMER3 */
+#else
+#define TIMER_CPU0    0x90 /* TIMER10 */
+#define TIMER10_IRQ_IDX    10
+#define IRQ_IDX_FOR_CPU(cpu)    (TIMER10_IRQ_IDX + cpu)
+#endif
+#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)
+
+static u32 usec_config;
   static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
   static void __iomem *rtc_base;
-
   static struct timespec64 persistent_ts;
   static u64 persistent_ms, last_persistent_ms;
-
   static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-    writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-    readl_relaxed(timer_reg_base + (reg))
+#endif
     static int tegra_timer_set_next_event(unsigned long cycles,
    struct clock_event_device *evt)
   {
-    u32 reg;
+    void __iomem *reg_base = timer_of_base(to_timer_of(evt));
   -    reg = 0x8000 | ((cycles > 1) ? (cycles-1) : 0);
-    timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+    writel(TIMER_PTV_EN |
+   ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+   reg_base + TIMER_PTV);
     return 0;
   }
   -static inline void timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_shutdown(struct clock_event_device *evt)
   {
-    timer_writel(0, TIMER3_BASE + TIMER_PTV);
+    void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+    writel(0, reg_base + TIMER_PTV);
+
+    return 0;
   }
   -static int tegra_timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_set_periodic(struct clock_event_device *evt)
   {
-    timer_shutdown(evt);
+    void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+    writel(TIMER_PTV_EN | TIMER_PTV_PER |
+   ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+   reg_base + TIMER_PTV);
+
   return 0;
   }
   -static int tegra_timer_set_periodic(struct clock_event_device *evt)
+static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
   {
-    u32 reg = 0xC000 | ((100 / HZ) - 1);
+    struct clock_event_device *evt = (struct clock_ev

Re: [PATCH V6 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-18 Thread Joseph Lo

On 2/15/19 11:14 PM, Daniel Lezcano wrote:

On 01/02/2019 17:16, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
Acked-by: Jon Hunter 
---
v6:
  * refine the timer defines
  * add ack tag from Jon.
v5:
  * add ack tag from Thierry
v4:
  * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
  * use timer-of API
v2:
  * add error clean-up code
---
  drivers/clocksource/Kconfig |   2 +-
  drivers/clocksource/timer-tegra20.c | 371 
  include/linux/cpuhotplug.h  |   1 +
  3 files changed, 270 insertions(+), 104 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..6af78534a285 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,7 @@ config SUN5I_HSTIMER
  config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM


This will break because the delay functions are defined in
arch/arm/include/asm/delay.h and the 01.org will try to compile the
driver on x86.

You may want to add 'depends on ARM && ARM64'



OK, I think it's 'depends on ARM || ARM64'.
Will fix.


+   select TIMER_OF
help
  Enables support for the Tegra driver.
  

[snip]

-
  static struct timespec64 persistent_ts;
  static u64 persistent_ms, last_persistent_ms;


Did you check the above changes are still relevant after commit
39232ed5a1793f67 and after doing a change similar to
commit 1569557549697207e523 ?



Yes, just check both commits. I think it's okay to use the same. But 
need another patch to do that, this patch only adds new support for 
Tegra210. Doesn't touch the original code.





  static struct delay_timer tegra_delay_timer;

[snip]

+#ifdef CONFIG_ARM64
+static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
+   .flags = TIMER_OF_CLOCK | TIMER_OF_BASE,
+
+   .clkevt = {
+   .name = "tegra_timer",
+   .rating = 460,
+   .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,


CLOCK_EVT_FEAT_DYNIRQ ?

Yes, good catch.



+   .set_next_event = tegra_timer_set_next_event,
+   .set_state_shutdown = tegra_timer_shutdown,
+   .set_state_periodic = tegra_timer_set_periodic,
+   .set_state_oneshot = tegra_timer_shutdown,
+   .tick_resume = tegra_timer_shutdown,
+   },
+};

[snip]

-static unsigned long tegra_delay_timer_read_counter_long(void)
+static int tegra_timer_suspend(void)
  {
-   return readl(timer_reg_base + TIMERUS_CNTR_1US);
+#ifdef CONFIG_ARM64


Please do not add those #ifdef but function stubs.


+   int cpu;
+
+   for_each_possible_cpu(cpu) {
+   struct timer_of *to = per_cpu_ptr(_to, cpu);
+   void __iomem *reg_base = timer_of_base(to);
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+   }
+#else
+   void __iomem *reg_base = timer_of_base(_to);
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+#endif
+
+   return 0;
  }
  
-static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)

+static void tegra_timer_resume(void)
  {
-   struct clock_event_device *evt = (struct clock_event_device *)dev_id;
-   timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
-   evt->event_handler(evt);
-   return IRQ_HANDLED;
+   writel(usec_config, timer_reg_base + TIMERUS_USEC_CFG);
  }
  
-static struct irqaction tegra_timer_irq = {

-   .name   = "timer0",
-   .flags  = IRQF_TIMER | IRQF_TRIGGER_HIGH,
-   .handler= tegra_timer_interrupt,
-   .dev_id = _clockevent,
+static struct syscore_ops tegra_timer_syscore_ops = {
+   .suspend = tegra_timer_suspend,
+   .resume = tegra_timer_resume,
  };


It will be nicer to use the suspend/resume callbacks defined in the
clockevent structure, so you can use generic as there are multiple
clockevents defined for the tegra210, thus multiple timer-of
encapsulating them. When the suspend/resume callbacks are called, they
have the clock_event pointer and you can use it to retrieve the timer-of
and then the base address. At the end, the callbacks will end up the
same for tegra20 and tegra210.



Very good suggestion, will follow up.


-static int __init tegra20_init_timer(struct device_node *np)
+static int tegra_timer_init(struct device_node *np, struct timer_of 

[PATCH V5 2/7] clocksource: tegra: add Tegra210 timer support

2019-01-31 Thread Joseph Lo
Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
---
v5:
 * add ack tag from Thierry
v4:
 * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
 * use timer-of API
v2:
 * add error clean-up code
---
 drivers/clocksource/Kconfig |   2 +-
 drivers/clocksource/timer-tegra20.c | 369 
 include/linux/cpuhotplug.h  |   1 +
 3 files changed, 272 insertions(+), 100 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..6af78534a285 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,7 @@ config SUN5I_HSTIMER
 config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM
+   select TIMER_OF
help
  Enables support for the Tegra driver.
 
diff --git a/drivers/clocksource/timer-tegra20.c 
b/drivers/clocksource/timer-tegra20.c
index 4293943f4e2b..96a809341c9b 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
  *
  */
 
-#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
-#include 
-#include 
+#include 
+#include 
+#include 
+
+#include "timer-of.h"
 
+#ifdef CONFIG_ARM
 #include 
+#endif
 
 #define RTC_SECONDS0x08
 #define RTC_SHADOW_SECONDS 0x0c
@@ -43,70 +46,147 @@
 #define TIMER2_BASE 0x8
 #define TIMER3_BASE 0x50
 #define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER10_BASE 0x90
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_BASE TIMER3_BASE
+#else
+#define TIMER_BASE TIMER10_BASE
+#endif
+#define TIMER10_IRQ_IDX10
+#define TIMER_FOR_CPU(cpu) (TIMER_BASE + (cpu) * 8)
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+
+static u32 usec_config;
 static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
 static void __iomem *rtc_base;
-
 static struct timespec64 persistent_ts;
 static u64 persistent_ms, last_persistent_ms;
-
 static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-   writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-   readl_relaxed(timer_reg_base + (reg))
+#endif
 
 static int tegra_timer_set_next_event(unsigned long cycles,
 struct clock_event_device *evt)
 {
-   u32 reg;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
 
-   reg = 0x8000 | ((cycles > 1) ? (cycles-1) : 0);
-   timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  reg_base + TIMER_PTV);
 
return 0;
 }
 
-static inline void timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_shutdown(struct clock_event_device *evt)
 {
-   timer_writel(0, TIMER3_BASE + TIMER_PTV);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(0, reg_base + TIMER_PTV);
+
+   return 0;
 }
 
-static int tegra_timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_set_periodic(struct clock_event_device *evt)
 {
-   timer_shutdown(evt);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PTV_EN | TIMER_PTV_PER |
+  ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+  reg_base + TIMER_PTV);
+
return 0;
 }
 
-static int tegra_timer_set_periodic(struct clock_event_device *evt)
+static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
 {
-   u32 reg = 0xC000 | ((100 / HZ) - 1);
+   struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+   evt->event_handler(evt);
+
+   return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_ARM64
+static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
+   .flags = TIMER_OF_CLOCK | TIMER_OF_BASE,
+
+   .clkevt = {
+   .name = "tegra_timer",
+   .rating = 460,
+   .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_O

[PATCH V5 1/7] dt-bindings: timer: add Tegra210 timer

2019-01-31 Thread Joseph Lo
The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: Joseph Lo 
Reviewed-by: Rob Herring 
---
v5:
 * no change
v4:
 * no change
v3:
 * no change
v2:
 * list all the interrupts that are supported by tegra210 timers block
 * add RB tag from Rob.
---
 .../bindings/timer/nvidia,tegra210-timer.txt  | 36 +++
 1 file changed, 36 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt 
b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index ..032cda96fe0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,36 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 14 interrupts; one per each timer channels 0 through
+  13.
+- clocks : Must contain one entry, for the module clock.
+  See ../clocks/clock-bindings.txt for details.
+
+timer@60005000 {
+   compatible = "nvidia,tegra210-timer";
+   reg = <0x0 0x60005000 0x0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = <_car TEGRA210_CLK_TIMER>;
+   clock-names = "timer";
+};
-- 
2.20.1



Re: [PATCH V5 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-01 Thread Joseph Lo

On 2/1/19 9:54 PM, Jon Hunter wrote:


On 01/02/2019 13:11, Dmitry Osipenko wrote:

01.02.2019 16:06, Dmitry Osipenko пишет:

01.02.2019 6:36, Joseph Lo пишет:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
---
v5:
  * add ack tag from Thierry
v4:
  * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
  * use timer-of API
v2:
  * add error clean-up code
---
  drivers/clocksource/Kconfig |   2 +-
  drivers/clocksource/timer-tegra20.c | 369 
  include/linux/cpuhotplug.h  |   1 +
  3 files changed, 272 insertions(+), 100 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..6af78534a285 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,7 @@ config SUN5I_HSTIMER
  config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM
+   select TIMER_OF
help
  Enables support for the Tegra driver.
  
diff --git a/drivers/clocksource/timer-tegra20.c b/drivers/clocksource/timer-tegra20.c

index 4293943f4e2b..96a809341c9b 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
   *
   */
  
-#include 

+#include 
+#include 
+#include 
+#include 
+#include 
  #include 
-#include 
  #include 
-#include 
-#include 
-#include 
-#include 
-#include 
  #include 
  #include 
-#include 
-#include 
+#include 
+#include 
+#include 
+
+#include "timer-of.h"
  
+#ifdef CONFIG_ARM

  #include 
+#endif
  
  #define RTC_SECONDS0x08

  #define RTC_SHADOW_SECONDS 0x0c
@@ -43,70 +46,147 @@
  #define TIMER2_BASE 0x8
  #define TIMER3_BASE 0x50
  #define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER10_BASE 0x90
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_BASE TIMER3_BASE
+#else
+#define TIMER_BASE TIMER10_BASE
+#endif
+#define TIMER10_IRQ_IDX10
+#define TIMER_FOR_CPU(cpu) (TIMER_BASE + (cpu) * 8)
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+
+static u32 usec_config;
  static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
  static void __iomem *rtc_base;
-
  static struct timespec64 persistent_ts;
  static u64 persistent_ms, last_persistent_ms;
-
  static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-   writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-   readl_relaxed(timer_reg_base + (reg))
+#endif
  
  static int tegra_timer_set_next_event(unsigned long cycles,

 struct clock_event_device *evt)
  {
-   u32 reg;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
  
-	reg = 0x8000 | ((cycles > 1) ? (cycles-1) : 0);

-   timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  reg_base + TIMER_PTV);
  
  	return 0;

  }
  
-static inline void timer_shutdown(struct clock_event_device *evt)

+static int tegra_timer_shutdown(struct clock_event_device *evt)
  {
-   timer_writel(0, TIMER3_BASE + TIMER_PTV);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(0, reg_base + TIMER_PTV);
+
+   return 0;
  }
  
-static int tegra_timer_shutdown(struct clock_event_device *evt)

+static int tegra_timer_set_periodic(struct clock_event_device *evt)
  {
-   timer_shutdown(evt);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PTV_EN | TIMER_PTV_PER |
+  ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+  reg_base + TIMER_PTV);
+
return 0;
  }
  
-static int tegra_timer_set_periodic(struct clock_event_device *evt)

+static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
  {
-   u32 reg = 0xC000 | ((100 / HZ) - 1);
+   struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+   evt->event_handler(evt);
+
+   return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_ARM64
+static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
+   .flags = T

Re: [PATCH V5 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-01 Thread Joseph Lo

On 2/1/19 8:44 PM, Jon Hunter wrote:


On 01/02/2019 03:36, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.


It may have been nice to split this into 2 patches to make it easier to
see what is going on but not a big deal.


Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
---
v5:
  * add ack tag from Thierry
v4:
  * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
  * use timer-of API
v2:
  * add error clean-up code
---
  drivers/clocksource/Kconfig |   2 +-
  drivers/clocksource/timer-tegra20.c | 369 
  include/linux/cpuhotplug.h  |   1 +
  3 files changed, 272 insertions(+), 100 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..6af78534a285 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,7 @@ config SUN5I_HSTIMER
  config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM
+   select TIMER_OF
help
  Enables support for the Tegra driver.
  
diff --git a/drivers/clocksource/timer-tegra20.c b/drivers/clocksource/timer-tegra20.c

index 4293943f4e2b..96a809341c9b 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
   *
   */
  
-#include 

+#include 
+#include 
+#include 
+#include 
+#include 
  #include 
-#include 
  #include 
-#include 
-#include 
-#include 
-#include 
-#include 
  #include 
  #include 
-#include 
-#include 
+#include 
+#include 
+#include 
+
+#include "timer-of.h"
  
+#ifdef CONFIG_ARM

  #include 
+#endif
  
  #define RTC_SECONDS0x08

  #define RTC_SHADOW_SECONDS 0x0c
@@ -43,70 +46,147 @@
  #define TIMER2_BASE 0x8
  #define TIMER3_BASE 0x50
  #define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER10_BASE 0x90
+
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_BASE TIMER3_BASE
+#else
+#define TIMER_BASE TIMER10_BASE
+#endif
+#define TIMER10_IRQ_IDX10
+#define TIMER_FOR_CPU(cpu) (TIMER_BASE + (cpu) * 8)
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)


TIMER10_IRQ_IDX and IRQ_IDX_FOR_CPU are only applicable to ARM64 and so
we should probably not defined for ARM to avoid any confusion.

Okay, will do.


Furthermore, a lot of these TIMERx_BASE definitions are unused AFAICT.
Would be good to get rid of these.


Okay.


Maybe we could just have ...

  +#ifdef CONFIG_ARM
  +#define TIMER_CPU0 3
  +#else
  +#define TIMER_CPU0 10
  +#endif
  +#define TIMER_BASE_FOR_CPU(cpu) ((TIMER_CPU0 + cpu) * 8)
  +#define TIMER_FOR_CPU(cpu) (TIMER_CPU0 + cpu)


This can't get the timer base address. I think you mean ...

+#ifdef CONFIG_ARM
+#define TIMER_CPU0 0x50 /* TIMER3 */
+#else
+#define TIMER_CPU0 0x90 /* TIMER10 */
+#endif
+#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)

This doesn't need.
+#define TIMER_FOR_CPU(cpu) (TIMER_CPU0 + cpu)

Will fix above accordingly and adding your ack tag.

Thanks,
Joseph


Otherwise looks good to me.

Cheers
Jon



Re: [PATCH V5 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-01 Thread Joseph Lo

On 2/1/19 11:13 PM, Dmitry Osipenko wrote:

01.02.2019 17:13, Joseph Lo пишет:

On 2/1/19 9:54 PM, Jon Hunter wrote:


On 01/02/2019 13:11, Dmitry Osipenko wrote:

01.02.2019 16:06, Dmitry Osipenko пишет:

01.02.2019 6:36, Joseph Lo пишет:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
---

snip.

+}
+TIMER_OF_DECLARE(tegra210_timer, "nvidia,tegra210-timer", tegra210_timer_init);
+#else /* CONFIG_ARM */
+static int __init tegra20_init_timer(struct device_node *np)
+{

What about T132? Isn't it ARM64 which uses tegra20-timer IP? At least T132 DT 
suggests so and seems this change will break it.

[snip]



Ah, noticed the "depends on ARM" in Kconfig.. Seems okay then.




This is a good point, because even though we had 'depends on ARM', this
still means that the Tegra132 DT is incorrect.

Joseph, can you take a quick look at Tegra132?


Hi Jon and Dmitry,

No worry about T132, T132 uses arch timer (v7). The tegra20 timer driver has 
never been used. We should fix the dtsi file later.


Hi Joseph,

So is T132 HW actually incompatible with the tegra20-timer? If it's compatible, 
then I think the driver's code should be made more universal to support T132.



From HW point of view, the TIMER1 ~ TIMER4 is compatible with 
"nvidia,tegra20-timer". But Tegra132 actually has 10 timers which are 
exactly the same as Tegra30. So it should backward compatible with 
"nvidia,tegra30-timer", which is tegra_wdt driver now. And Tegra132 
should never use this driver.


The Tegra timer driver should only be used on Tegra20/30/210, three 
platforms only. Others use arch timer driver for system timer driver.


So we don't really need to take care the usage on other Tegra platforms.

Thanks,
Joseph


Re: [PATCH V5 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-01 Thread Joseph Lo

On 2/1/19 11:43 PM, Jon Hunter wrote:



On 01/02/2019 14:39, Joseph Lo wrote:

On 2/1/19 8:44 PM, Jon Hunter wrote:


On 01/02/2019 03:36, Joseph Lo wrote:

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a
wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.


It may have been nice to split this into 2 patches to make it easier to
see what is going on but not a big deal.


Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
---

snip.



This can't get the timer base address. I think you mean ...

+#ifdef CONFIG_ARM
+#define TIMER_CPU0 0x50 /* TIMER3 */
+#else
+#define TIMER_CPU0 0x90 /* TIMER10 */
+#endif
+#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)


Ah I see.


This doesn't need.
+#define TIMER_FOR_CPU(cpu) (TIMER_CPU0 + cpu)

How come? Don't you still need to know the timer index for a given CPU?



Doesn't need. TIMER_BASE_FOR_CPU is enough. Other use cases are well 
handled by timer-of API. :)


Thanks,
Joseph


[PATCH V6 2/7] clocksource: tegra: add Tegra210 timer support

2019-02-01 Thread Joseph Lo
Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo 
Acked-by: Thierry Reding 
Acked-by: Jon Hunter 
---
v6:
 * refine the timer defines
 * add ack tag from Jon.
v5:
 * add ack tag from Thierry
v4:
 * merge timer-tegra210.c in previous version into timer-tegra20.c
v3:
 * use timer-of API
v2:
 * add error clean-up code
---
 drivers/clocksource/Kconfig |   2 +-
 drivers/clocksource/timer-tegra20.c | 371 
 include/linux/cpuhotplug.h  |   1 +
 3 files changed, 270 insertions(+), 104 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..6af78534a285 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,7 @@ config SUN5I_HSTIMER
 config TEGRA_TIMER
bool "Tegra timer driver" if COMPILE_TEST
select CLKSRC_MMIO
-   depends on ARM
+   select TIMER_OF
help
  Enables support for the Tegra driver.
 
diff --git a/drivers/clocksource/timer-tegra20.c 
b/drivers/clocksource/timer-tegra20.c
index 4293943f4e2b..f66edd63d7f4 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
  *
  */
 
-#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
-#include 
-#include 
+#include 
+#include 
+#include 
+
+#include "timer-of.h"
 
+#ifdef CONFIG_ARM
 #include 
+#endif
 
 #define RTC_SECONDS0x08
 #define RTC_SHADOW_SECONDS 0x0c
@@ -39,74 +42,145 @@
 #define TIMERUS_USEC_CFG 0x14
 #define TIMERUS_CNTR_FREEZE 0x4c
 
-#define TIMER1_BASE 0x0
-#define TIMER2_BASE 0x8
-#define TIMER3_BASE 0x50
-#define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER_PTV  0x0
+#define TIMER_PTV_EN   BIT(31)
+#define TIMER_PTV_PER  BIT(30)
+#define TIMER_PCR  0x4
+#define TIMER_PCR_INTR_CLR BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_CPU0 0x50 /* TIMER3 */
+#else
+#define TIMER_CPU0 0x90 /* TIMER10 */
+#define TIMER10_IRQ_IDX10
+#define IRQ_IDX_FOR_CPU(cpu)   (TIMER10_IRQ_IDX + cpu)
+#endif
+#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)
+
+static u32 usec_config;
 static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
 static void __iomem *rtc_base;
-
 static struct timespec64 persistent_ts;
 static u64 persistent_ms, last_persistent_ms;
-
 static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-   writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-   readl_relaxed(timer_reg_base + (reg))
+#endif
 
 static int tegra_timer_set_next_event(unsigned long cycles,
 struct clock_event_device *evt)
 {
-   u32 reg;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
 
-   reg = 0x8000 | ((cycles > 1) ? (cycles-1) : 0);
-   timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+   writel(TIMER_PTV_EN |
+  ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+  reg_base + TIMER_PTV);
 
return 0;
 }
 
-static inline void timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_shutdown(struct clock_event_device *evt)
 {
-   timer_writel(0, TIMER3_BASE + TIMER_PTV);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(0, reg_base + TIMER_PTV);
+
+   return 0;
 }
 
-static int tegra_timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_set_periodic(struct clock_event_device *evt)
 {
-   timer_shutdown(evt);
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PTV_EN | TIMER_PTV_PER |
+  ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+  reg_base + TIMER_PTV);
+
return 0;
 }
 
-static int tegra_timer_set_periodic(struct clock_event_device *evt)
+static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
 {
-   u32 reg = 0xC000 | ((100 / HZ) - 1);
+   struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+   void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+   writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+   evt->event_handler(evt);
+
+   return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_ARM64
+static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
+   .flags = TIMER_OF_CLOCK | TIM

[PATCH V6 1/7] dt-bindings: timer: add Tegra210 timer

2019-02-01 Thread Joseph Lo
The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: Joseph Lo 
Reviewed-by: Rob Herring 
Acked-by: Jon Hunter 
---
v6:
 * add ack tag from Jon.
v5:
 * no change
v4:
 * no change
v3:
 * no change
v2:
 * list all the interrupts that are supported by tegra210 timers block
 * add RB tag from Rob.
---
 .../bindings/timer/nvidia,tegra210-timer.txt  | 36 +++
 1 file changed, 36 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt 
b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index ..032cda96fe0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,36 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 14 interrupts; one per each timer channels 0 through
+  13.
+- clocks : Must contain one entry, for the module clock.
+  See ../clocks/clock-bindings.txt for details.
+
+timer@60005000 {
+   compatible = "nvidia,tegra210-timer";
+   reg = <0x0 0x60005000 0x0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = <_car TEGRA210_CLK_TIMER>;
+   clock-names = "timer";
+};
-- 
2.20.1



  1   2   >