Re:Re: Question about "Make sched entity usage tracking scale-invariant"

2015-05-26 Thread Chao Xie

At 2015-05-26 19:05:36, "Morten Rasmussen"  wrote:
>Hi,
>
>[Adding maintainers and others to cc]
>
>On Mon, May 25, 2015 at 02:19:43AM +0100, Chao Xie wrote:
>> hi
>> I saw the patch “sched: Make sched entity usage tracking
>> scale-invariant” that will make the usage to be freq scaled.
>> So if delta period that the calculation of usage based on cross a
>> frequency change, so how can you make sure the usage calculation is
>> correct?
>> The delta period may last hundreds of microseconds, and frequency
>> change window may be 10-20 microseconds, so many frequency change can
>> happen during the delta period.
>> It seems the patch does not consider about it, and it just pick up the
>> current one.
>> So how can you resolve this issue?
>
>Right. We don't know how many times the frequency may have changed since
>last time we updated the entity usage tracking for the particular
>entity. All we do is to call arch_scale_freq_capacity() and use that
>scaling factor to compensate for whatever changes might have taken
>place.
>
>The easiest implementation of arch_scale_freq_capacity() for most
>architectures is to just return a scaling factor computed based on the
>current frequency and ignoring when exactly the change happened and
>ignoring if multiple changes happened. Depending on how often the
>frequency might change this might be an acceptable approximation. While
>the task is running the sched tick will update the entity usage tracking
>(every 10ms by default on most ARM systems), hence we shouldn't be more
>than a tick off in term of when the frequency change is accounted for.
>Under normal circumstances the delta period should therefore be <10ms
>and generally shorter than that if you have more than one task runnable
>on the cpu or the task(s) are not always-running. It is not perfect but
>it is a lot better than the utilization tracking currently used by
>cpufreq governors and better than the scheduler being completely unaware
>of frequency scaling.
>
>For systems with very frequent frequency changes, i.e. fast hardware and
>an aggressive governor leading to multiple changes in less than 10ms,
>the solution above might not be sufficient. In that case, I think a
>better solution might be to track the average frequency using hardware
>counters or whatever tracking metrics the system might have to let
>arch_scale_freq_capacity() return the average performance delivered over
>the most recent period of time. AFAIK, x86 already has performance
>counters (APERF/MPERF) that could be used for this purpose. The delta
>period for each entity tracking update isn't fixed, but it might
>sufficient to just average over some fixed period of time. Accurate
>tracking would require some time-stamp information to be stored in each
>sched_entity for the true average to be computed for the delta period.
>That quickly becomes rather messy but not impossible. I did look at it
>briefly a while back, but decided not to go down that route until we
>know that using current frequency or some fixed period average isn't
>going to be sufficient. Usage or utilization is and average of something
>that might be constantly changing anyways, so it never going to be very
>accurate anyway. If it does turn out that we can't get the overall
>picture right, we will need to improve it.
>
>Updating the entity tracking for each frequency change adds to much
>overhead I think and seems unnecessary if we do with an average scaling
>factor.
>
>I hope that answers your question. Have you observed any problems with
>the usage tracking?
>

Thanks for the explanation.

I agree that the "delta" is less than 10ms at most situation, but i think at 
least one period
need to be considered.
If the frequency change happens just a little, for example, 10us before the 
task start to
calculate its utilization which may have a delta of 10ms. The almost whole 
delta will be calculated
based on new frequency, not the old one. The frequency change can be from the 
lowest to highest,
so for this time the delta calculation has big deviation, and this situation is 
not rare.

>Thanks,
>Morten


Re:Re: Question about Make sched entity usage tracking scale-invariant

2015-05-26 Thread Chao Xie

At 2015-05-26 19:05:36, Morten Rasmussen morten.rasmus...@arm.com wrote:
Hi,

[Adding maintainers and others to cc]

On Mon, May 25, 2015 at 02:19:43AM +0100, Chao Xie wrote:
 hi
 I saw the patch “sched: Make sched entity usage tracking
 scale-invariant” that will make the usage to be freq scaled.
 So if delta period that the calculation of usage based on cross a
 frequency change, so how can you make sure the usage calculation is
 correct?
 The delta period may last hundreds of microseconds, and frequency
 change window may be 10-20 microseconds, so many frequency change can
 happen during the delta period.
 It seems the patch does not consider about it, and it just pick up the
 current one.
 So how can you resolve this issue?

Right. We don't know how many times the frequency may have changed since
last time we updated the entity usage tracking for the particular
entity. All we do is to call arch_scale_freq_capacity() and use that
scaling factor to compensate for whatever changes might have taken
place.

The easiest implementation of arch_scale_freq_capacity() for most
architectures is to just return a scaling factor computed based on the
current frequency and ignoring when exactly the change happened and
ignoring if multiple changes happened. Depending on how often the
frequency might change this might be an acceptable approximation. While
the task is running the sched tick will update the entity usage tracking
(every 10ms by default on most ARM systems), hence we shouldn't be more
than a tick off in term of when the frequency change is accounted for.
Under normal circumstances the delta period should therefore be 10ms
and generally shorter than that if you have more than one task runnable
on the cpu or the task(s) are not always-running. It is not perfect but
it is a lot better than the utilization tracking currently used by
cpufreq governors and better than the scheduler being completely unaware
of frequency scaling.

For systems with very frequent frequency changes, i.e. fast hardware and
an aggressive governor leading to multiple changes in less than 10ms,
the solution above might not be sufficient. In that case, I think a
better solution might be to track the average frequency using hardware
counters or whatever tracking metrics the system might have to let
arch_scale_freq_capacity() return the average performance delivered over
the most recent period of time. AFAIK, x86 already has performance
counters (APERF/MPERF) that could be used for this purpose. The delta
period for each entity tracking update isn't fixed, but it might
sufficient to just average over some fixed period of time. Accurate
tracking would require some time-stamp information to be stored in each
sched_entity for the true average to be computed for the delta period.
That quickly becomes rather messy but not impossible. I did look at it
briefly a while back, but decided not to go down that route until we
know that using current frequency or some fixed period average isn't
going to be sufficient. Usage or utilization is and average of something
that might be constantly changing anyways, so it never going to be very
accurate anyway. If it does turn out that we can't get the overall
picture right, we will need to improve it.

Updating the entity tracking for each frequency change adds to much
overhead I think and seems unnecessary if we do with an average scaling
factor.

I hope that answers your question. Have you observed any problems with
the usage tracking?


Thanks for the explanation.

I agree that the delta is less than 10ms at most situation, but i think at 
least one period
need to be considered.
If the frequency change happens just a little, for example, 10us before the 
task start to
calculate its utilization which may have a delta of 10ms. The almost whole 
delta will be calculated
based on new frequency, not the old one. The frequency change can be from the 
lowest to highest,
so for this time the delta calculation has big deviation, and this situation is 
not rare.

Thanks,
Morten


Question about "Make sched entity usage tracking scale-invariant"

2015-05-24 Thread Chao Xie
hi
I saw the patch “sched: Make sched entity usage tracking scale-invariant” that 
will make the usage to be freq scaled.
So if delta period that the calculation of usage based on cross a frequency 
change, so how can you make sure the usage calculation is correct?
The delta period may last hundreds of microseconds, and frequency change window 
may be 10-20 microseconds, so many frequency change can happen during the delta 
period.
It seems the patch does not consider about it, and it just pick up the current 
one.
So how can you resolve this issue?

Thanks.N嫥叉靣笡y氊b瞂千v豝�)藓{.n�+壏{睉赙zXФ洝塄}财爖�:+v墾�珣赙zZ+€�+zf"穐殘啳嗃iz�畐ア�?櫒璀�&�)撷f旟^j谦y呩@A玜囤
0鹅h�鍜i

Question about Make sched entity usage tracking scale-invariant

2015-05-24 Thread Chao Xie
hi
I saw the patch “sched: Make sched entity usage tracking scale-invariant” that 
will make the usage to be freq scaled.
So if delta period that the calculation of usage based on cross a frequency 
change, so how can you make sure the usage calculation is correct?
The delta period may last hundreds of microseconds, and frequency change window 
may be 10-20 microseconds, so many frequency change can happen during the delta 
period.
It seems the patch does not consider about it, and it just pick up the current 
one.
So how can you resolve this issue?

Thanks.N嫥叉靣笡y氊b瞂千v豝�)藓{.n�+壏{睉赙zXФ洝塄}财爖�j:+v墾�珣赙zZ+€�+zf"穐殘啳嗃iz�畐ア�?櫒璀��)撷f旟^j谦y呩@A玜囤
0鹅h�鍜i

[PATCH RESEND 3/3] clk: mmp: add timer clock for pxa168/mmp2/pxa910

2015-04-29 Thread Chao Xie
From: Chao Xie 

Timer has external fast clock, and it is a mux clock.
Add the timer clock type for timer driver.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-of-mmp2.c  |  6 ++
 drivers/clk/mmp/clk-of-pxa168.c|  7 +++
 drivers/clk/mmp/clk-of-pxa910.c| 11 +++
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  2 ++
 include/dt-bindings/clock/marvell,pxa910.h |  3 +++
 6 files changed, 30 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index b7e0b89..251533d 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -30,6 +30,7 @@
 #define APBC_TWSI4 0x7c
 #define APBC_TWSI5 0x80
 #define APBC_KPC   0x18
+#define APBC_TIMER 0x24
 #define APBC_UART0 0x2c
 #define APBC_UART1 0x30
 #define APBC_UART2 0x34
@@ -132,6 +133,9 @@ static DEFINE_SPINLOCK(ssp2_lock);
 static DEFINE_SPINLOCK(ssp3_lock);
 static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", 
"pll1_16"};
 
+static DEFINE_SPINLOCK(timer_lock);
+static const char *timer_parent_names[] = {"clk32", "vctcxo_2", "vctcxo_4", 
"vctcxo"};
+
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -143,6 +147,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
{0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, _lock},
{0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, _lock},
{0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, _lock},
+   {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), 
CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, _lock},
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -168,6 +173,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
{MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 
0x7, 0x3, 0x0, 0, _lock},
{MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 
0x7, 0x3, 0x0, 0, _lock},
{MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 
0x7, 0x3, 0x0, 0, _lock},
+   {MMP2_CLK_TIMER, "timer_clk", "timer_mux", CLK_SET_RATE_PARENT, 
APBC_TIMER, 0x7, 0x3, 0x0, 0, _lock},
 };
 
 static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 01a650e..64eaf41 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -32,6 +32,7 @@
 #define APBC_PWM1  0x10
 #define APBC_PWM2  0x14
 #define APBC_PWM3  0x18
+#define APBC_TIMER 0x34
 #define APBC_SSP0  0x81c
 #define APBC_SSP1  0x820
 #define APBC_SSP2  0x84c
@@ -71,6 +72,7 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] 
= {
{PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
{PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
{PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
+   {PXA168_CLK_PLL1_192, "pll1_192", "pll1_96", 1, 2, 0},
{PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
{PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
{PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
@@ -120,6 +122,9 @@ static DEFINE_SPINLOCK(ssp3_lock);
 static DEFINE_SPINLOCK(ssp4_lock);
 static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", 
"pll1_12"};
 
+static DEFINE_SPINLOCK(timer_lock);
+static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96", 
"pll1_192"};
+
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -131,6 +136,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
{0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, _lock},
{0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, _lock},
{0, "ssp4_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, _lock},
+   {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), 
CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, _lock},
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -152,6 +158,7 @@ static struct mmp_param_gate_cl

[PATCH RESEND 1/3] clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168

2015-04-29 Thread Chao Xie
From: Chao Xie 

USB will drive clock from USB_PLL.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-of-pxa168.c| 1 +
 drivers/clk/mmp/clk-of-pxa910.c| 1 +
 include/dt-bindings/clock/marvell,pxa168.h | 1 +
 include/dt-bindings/clock/marvell,pxa910.h | 1 +
 4 files changed, 4 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 5b1810d..01a650e 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -58,6 +58,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
{PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
{PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 62400},
+   {PXA168_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 48000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
index 5e3c80d..cca98ef 100644
--- a/drivers/clk/mmp/clk-of-pxa910.c
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -57,6 +57,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
{PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
{PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 62400},
+   {PXA910_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 48000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/include/dt-bindings/clock/marvell,pxa168.h 
b/include/dt-bindings/clock/marvell,pxa168.h
index 79630b9..84ce5de 100644
--- a/include/dt-bindings/clock/marvell,pxa168.h
+++ b/include/dt-bindings/clock/marvell,pxa168.h
@@ -19,6 +19,7 @@
 #define PXA168_CLK_PLL1_2_1_5  19
 #define PXA168_CLK_PLL1_3_16   20
 #define PXA168_CLK_UART_PLL27
+#define PXA168_CLK_USB_PLL 28
 
 /* apb periphrals */
 #define PXA168_CLK_TWSI0   60
diff --git a/include/dt-bindings/clock/marvell,pxa910.h 
b/include/dt-bindings/clock/marvell,pxa910.h
index 719cffb..bea08b6 100644
--- a/include/dt-bindings/clock/marvell,pxa910.h
+++ b/include/dt-bindings/clock/marvell,pxa910.h
@@ -19,6 +19,7 @@
 #define PXA910_CLK_PLL1_2_1_5  19
 #define PXA910_CLK_PLL1_3_16   20
 #define PXA910_CLK_UART_PLL27
+#define PXA910_CLK_USB_PLL 28
 
 /* apb periphrals */
 #define PXA910_CLK_TWSI0   60
-- 
1.8.3.2

--
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 RESEND 2/3] clk: mmp: Fix the wrong factor table for uart PLL

2015-04-29 Thread Chao Xie
From: Chao Xie 

The suggested value in the mmp2 manual is wrong.
There are only 13 bits for numerator, but some suggested
value has 14 bits.
Fix the factor tabled and remove the unused items.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-mmp2.c| 4 +---
 drivers/clk/mmp/clk-of-mmp2.c | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 5c90a42..09d2832 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -63,10 +63,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
 };
 
 static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
-   {.num = 14634, .den = 2165},/*14.745MHZ */
+   {.num = 8125, .den = 1536}, /*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
-   {.num = 9679, .den = 5728}, /*58.9824MHZ */
-   {.num = 15850, .den = 9451},/*59.429MHZ */
 };
 
 static const char *uart_parent[] = {"uart_pll", "vctcxo"};
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 2cbc2b4..b7e0b89 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -98,10 +98,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
 };
 
 static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
-   {.num = 14634, .den = 2165},/*14.745MHZ */
+   {.num = 8125, .den = 1536}, /*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
-   {.num = 9679, .den = 5728}, /*58.9824MHZ */
-   {.num = 15850, .den = 9451},/*59.429MHZ */
 };
 
 static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
-- 
1.8.3.2

--
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 RESEND 0/3] clk: mmp: fix and add new clock

2015-04-29 Thread Chao Xie
From: Chao Xie 

There are three patches
First two are fix patches.
The last one will add the timer clock for pxa168/mmp2/pxa910.

The timer driver will make use of the timer clock.

Chao Xie (3):
  clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168
  clk: mmp: Fix the wrong factor table for uart PLL
  clk: mmp: add timer clock for pxa168/mmp2/pxa910

 drivers/clk/mmp/clk-mmp2.c |  4 +---
 drivers/clk/mmp/clk-of-mmp2.c  | 10 +++---
 drivers/clk/mmp/clk-of-pxa168.c|  8 
 drivers/clk/mmp/clk-of-pxa910.c| 12 
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  3 +++
 include/dt-bindings/clock/marvell,pxa910.h |  4 
 7 files changed, 36 insertions(+), 6 deletions(-)

-- 
1.8.3.2

--
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 RESEND 0/3] clk: mmp: fix and add new clock

2015-04-29 Thread Chao Xie
From: Chao Xie chao@marvell.com

There are three patches
First two are fix patches.
The last one will add the timer clock for pxa168/mmp2/pxa910.

The timer driver will make use of the timer clock.

Chao Xie (3):
  clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168
  clk: mmp: Fix the wrong factor table for uart PLL
  clk: mmp: add timer clock for pxa168/mmp2/pxa910

 drivers/clk/mmp/clk-mmp2.c |  4 +---
 drivers/clk/mmp/clk-of-mmp2.c  | 10 +++---
 drivers/clk/mmp/clk-of-pxa168.c|  8 
 drivers/clk/mmp/clk-of-pxa910.c| 12 
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  3 +++
 include/dt-bindings/clock/marvell,pxa910.h |  4 
 7 files changed, 36 insertions(+), 6 deletions(-)

-- 
1.8.3.2

--
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 RESEND 3/3] clk: mmp: add timer clock for pxa168/mmp2/pxa910

2015-04-29 Thread Chao Xie
From: Chao Xie chao@marvell.com

Timer has external fast clock, and it is a mux clock.
Add the timer clock type for timer driver.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-of-mmp2.c  |  6 ++
 drivers/clk/mmp/clk-of-pxa168.c|  7 +++
 drivers/clk/mmp/clk-of-pxa910.c| 11 +++
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  2 ++
 include/dt-bindings/clock/marvell,pxa910.h |  3 +++
 6 files changed, 30 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index b7e0b89..251533d 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -30,6 +30,7 @@
 #define APBC_TWSI4 0x7c
 #define APBC_TWSI5 0x80
 #define APBC_KPC   0x18
+#define APBC_TIMER 0x24
 #define APBC_UART0 0x2c
 #define APBC_UART1 0x30
 #define APBC_UART2 0x34
@@ -132,6 +133,9 @@ static DEFINE_SPINLOCK(ssp2_lock);
 static DEFINE_SPINLOCK(ssp3_lock);
 static const char *ssp_parent_names[] = {vctcxo_4, vctcxo_2, vctcxo, 
pll1_16};
 
+static DEFINE_SPINLOCK(timer_lock);
+static const char *timer_parent_names[] = {clk32, vctcxo_2, vctcxo_4, 
vctcxo};
+
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -143,6 +147,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
{0, ssp1_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, ssp1_lock},
{0, ssp2_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, ssp2_lock},
{0, ssp3_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, ssp3_lock},
+   {0, timer_mux, timer_parent_names, ARRAY_SIZE(timer_parent_names), 
CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, timer_lock},
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -168,6 +173,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
{MMP2_CLK_SSP1, ssp1_clk, ssp1_mux, CLK_SET_RATE_PARENT, APBC_SSP1, 
0x7, 0x3, 0x0, 0, ssp1_lock},
{MMP2_CLK_SSP2, ssp2_clk, ssp2_mux, CLK_SET_RATE_PARENT, APBC_SSP2, 
0x7, 0x3, 0x0, 0, ssp2_lock},
{MMP2_CLK_SSP3, ssp3_clk, ssp3_mux, CLK_SET_RATE_PARENT, APBC_SSP3, 
0x7, 0x3, 0x0, 0, ssp3_lock},
+   {MMP2_CLK_TIMER, timer_clk, timer_mux, CLK_SET_RATE_PARENT, 
APBC_TIMER, 0x7, 0x3, 0x0, 0, timer_lock},
 };
 
 static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 01a650e..64eaf41 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -32,6 +32,7 @@
 #define APBC_PWM1  0x10
 #define APBC_PWM2  0x14
 #define APBC_PWM3  0x18
+#define APBC_TIMER 0x34
 #define APBC_SSP0  0x81c
 #define APBC_SSP1  0x820
 #define APBC_SSP2  0x84c
@@ -71,6 +72,7 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] 
= {
{PXA168_CLK_PLL1_24, pll1_24, pll1_12, 1, 2, 0},
{PXA168_CLK_PLL1_48, pll1_48, pll1_24, 1, 2, 0},
{PXA168_CLK_PLL1_96, pll1_96, pll1_48, 1, 2, 0},
+   {PXA168_CLK_PLL1_192, pll1_192, pll1_96, 1, 2, 0},
{PXA168_CLK_PLL1_13, pll1_13, pll1, 1, 13, 0},
{PXA168_CLK_PLL1_13_1_5, pll1_13_1_5, pll1_13, 2, 3, 0},
{PXA168_CLK_PLL1_2_1_5, pll1_2_1_5, pll1_2, 2, 3, 0},
@@ -120,6 +122,9 @@ static DEFINE_SPINLOCK(ssp3_lock);
 static DEFINE_SPINLOCK(ssp4_lock);
 static const char *ssp_parent_names[] = {pll1_96, pll1_48, pll1_24, 
pll1_12};
 
+static DEFINE_SPINLOCK(timer_lock);
+static const char *timer_parent_names[] = {pll1_48, clk32, pll1_96, 
pll1_192};
+
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -131,6 +136,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
{0, ssp2_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, ssp2_lock},
{0, ssp3_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, ssp3_lock},
{0, ssp4_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, ssp4_lock},
+   {0, timer_mux, timer_parent_names, ARRAY_SIZE(timer_parent_names), 
CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, timer_lock},
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -152,6 +158,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
{PXA168_CLK_SSP2, ssp2_clk, ssp2_mux, CLK_SET_RATE_PARENT, 
APBC_SSP2, 0x3, 0x3, 0x0, 0, ssp2_lock},
{PXA168_CLK_SSP3, ssp3_clk, ssp3_mux, CLK_SET_RATE_PARENT, 
APBC_SSP3, 0x3, 0x3, 0x0, 0, ssp3_lock},
{PXA168_CLK_SSP4, ssp4_clk, ssp4_mux, CLK_SET_RATE_PARENT, 
APBC_SSP4, 0x3, 0x3, 0x0, 0, ssp4_lock},
+   {PXA168_CLK_TIMER, timer_clk, timer_mux, CLK_SET_RATE_PARENT, 
APBC_TIMER, 0x3, 0x3, 0x0, 0, timer_lock

[PATCH RESEND 1/3] clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168

2015-04-29 Thread Chao Xie
From: Chao Xie chao@marvell.com

USB will drive clock from USB_PLL.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-of-pxa168.c| 1 +
 drivers/clk/mmp/clk-of-pxa910.c| 1 +
 include/dt-bindings/clock/marvell,pxa168.h | 1 +
 include/dt-bindings/clock/marvell,pxa910.h | 1 +
 4 files changed, 4 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 5b1810d..01a650e 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -58,6 +58,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{PXA168_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
{PXA168_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
{PXA168_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 62400},
+   {PXA168_CLK_USB_PLL, usb_pll, NULL, CLK_IS_ROOT, 48000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
index 5e3c80d..cca98ef 100644
--- a/drivers/clk/mmp/clk-of-pxa910.c
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -57,6 +57,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{PXA910_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
{PXA910_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
{PXA910_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 62400},
+   {PXA910_CLK_USB_PLL, usb_pll, NULL, CLK_IS_ROOT, 48000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/include/dt-bindings/clock/marvell,pxa168.h 
b/include/dt-bindings/clock/marvell,pxa168.h
index 79630b9..84ce5de 100644
--- a/include/dt-bindings/clock/marvell,pxa168.h
+++ b/include/dt-bindings/clock/marvell,pxa168.h
@@ -19,6 +19,7 @@
 #define PXA168_CLK_PLL1_2_1_5  19
 #define PXA168_CLK_PLL1_3_16   20
 #define PXA168_CLK_UART_PLL27
+#define PXA168_CLK_USB_PLL 28
 
 /* apb periphrals */
 #define PXA168_CLK_TWSI0   60
diff --git a/include/dt-bindings/clock/marvell,pxa910.h 
b/include/dt-bindings/clock/marvell,pxa910.h
index 719cffb..bea08b6 100644
--- a/include/dt-bindings/clock/marvell,pxa910.h
+++ b/include/dt-bindings/clock/marvell,pxa910.h
@@ -19,6 +19,7 @@
 #define PXA910_CLK_PLL1_2_1_5  19
 #define PXA910_CLK_PLL1_3_16   20
 #define PXA910_CLK_UART_PLL27
+#define PXA910_CLK_USB_PLL 28
 
 /* apb periphrals */
 #define PXA910_CLK_TWSI0   60
-- 
1.8.3.2

--
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 RESEND 2/3] clk: mmp: Fix the wrong factor table for uart PLL

2015-04-29 Thread Chao Xie
From: Chao Xie chao@marvell.com

The suggested value in the mmp2 manual is wrong.
There are only 13 bits for numerator, but some suggested
value has 14 bits.
Fix the factor tabled and remove the unused items.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-mmp2.c| 4 +---
 drivers/clk/mmp/clk-of-mmp2.c | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 5c90a42..09d2832 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -63,10 +63,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
 };
 
 static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
-   {.num = 14634, .den = 2165},/*14.745MHZ */
+   {.num = 8125, .den = 1536}, /*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
-   {.num = 9679, .den = 5728}, /*58.9824MHZ */
-   {.num = 15850, .den = 9451},/*59.429MHZ */
 };
 
 static const char *uart_parent[] = {uart_pll, vctcxo};
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 2cbc2b4..b7e0b89 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -98,10 +98,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
 };
 
 static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
-   {.num = 14634, .den = 2165},/*14.745MHZ */
+   {.num = 8125, .den = 1536}, /*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
-   {.num = 9679, .den = 5728}, /*58.9824MHZ */
-   {.num = 15850, .den = 9451},/*59.429MHZ */
 };
 
 static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
-- 
1.8.3.2

--
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 0/3] clk: mmp: fix and add new clock

2015-04-22 Thread Chao Xie

hi, Mike


These patches are bug fix and enhancement patches for mmp clock. 


If it does not have any problem, can you help to merge it?


Thanks.



At 2015-04-07 14:17:01, "Chao Xie"  wrote:
>From: Chao Xie 
>
>There are three patches
>First two are fix patches.
>The last one will add the timer clock for pxa168/mmp2/pxa910.
>
>The timer driver will make use of the timer clock.
>
>Chao Xie (3):
>  clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168
>  clk: mmp: Fix the wrong factor table for uart PLL
>  clk: mmp: add timer clock for pxa168/mmp2/pxa910
>
> drivers/clk/mmp/clk-mmp2.c |  4 +---
> drivers/clk/mmp/clk-of-mmp2.c  | 10 +++---
> drivers/clk/mmp/clk-of-pxa168.c|  8 
> drivers/clk/mmp/clk-of-pxa910.c| 12 
> include/dt-bindings/clock/marvell,mmp2.h   |  1 +
> include/dt-bindings/clock/marvell,pxa168.h |  3 +++
> include/dt-bindings/clock/marvell,pxa910.h |  4 
> 7 files changed, 36 insertions(+), 6 deletions(-)
>
>-- 
>1.8.3.2
>
N�r��yb�X��ǧv�^�)޺{.n�+{zX����ܨ}���Ơz�:+v���zZ+��+zf���h���~i���z��w���?�&�)ߢf��^jǫy�m��@A�a���
0��h���i

Re:[PATCH 0/3] clk: mmp: fix and add new clock

2015-04-22 Thread Chao Xie

hi, Mike


These patches are bug fix and enhancement patches for mmp clock. 


If it does not have any problem, can you help to merge it?


Thanks.



At 2015-04-07 14:17:01, Chao Xie chao@marvell.com wrote:
From: Chao Xie chao@marvell.com

There are three patches
First two are fix patches.
The last one will add the timer clock for pxa168/mmp2/pxa910.

The timer driver will make use of the timer clock.

Chao Xie (3):
  clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168
  clk: mmp: Fix the wrong factor table for uart PLL
  clk: mmp: add timer clock for pxa168/mmp2/pxa910

 drivers/clk/mmp/clk-mmp2.c |  4 +---
 drivers/clk/mmp/clk-of-mmp2.c  | 10 +++---
 drivers/clk/mmp/clk-of-pxa168.c|  8 
 drivers/clk/mmp/clk-of-pxa910.c| 12 
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  3 +++
 include/dt-bindings/clock/marvell,pxa910.h |  4 
 7 files changed, 36 insertions(+), 6 deletions(-)

-- 
1.8.3.2

N�r��yb�X��ǧv�^�)޺{.n�+{zX����ܨ}���Ơz�j:+v���zZ+��+zf���h���~i���z��w���?��)ߢf��^jǫy�m��@A�a���
0��h���i

[PATCH 1/3] clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168

2015-04-07 Thread Chao Xie
From: Chao Xie 

USB will drive clock from USB_PLL.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-of-pxa168.c| 1 +
 drivers/clk/mmp/clk-of-pxa910.c| 1 +
 include/dt-bindings/clock/marvell,pxa168.h | 1 +
 include/dt-bindings/clock/marvell,pxa910.h | 1 +
 4 files changed, 4 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 5b1810d..01a650e 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -58,6 +58,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
{PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
{PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 62400},
+   {PXA168_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 48000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
index 5e3c80d..cca98ef 100644
--- a/drivers/clk/mmp/clk-of-pxa910.c
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -57,6 +57,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
{PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
{PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 62400},
+   {PXA910_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 48000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/include/dt-bindings/clock/marvell,pxa168.h 
b/include/dt-bindings/clock/marvell,pxa168.h
index 79630b9..84ce5de 100644
--- a/include/dt-bindings/clock/marvell,pxa168.h
+++ b/include/dt-bindings/clock/marvell,pxa168.h
@@ -19,6 +19,7 @@
 #define PXA168_CLK_PLL1_2_1_5  19
 #define PXA168_CLK_PLL1_3_16   20
 #define PXA168_CLK_UART_PLL27
+#define PXA168_CLK_USB_PLL 28
 
 /* apb periphrals */
 #define PXA168_CLK_TWSI0   60
diff --git a/include/dt-bindings/clock/marvell,pxa910.h 
b/include/dt-bindings/clock/marvell,pxa910.h
index 719cffb..bea08b6 100644
--- a/include/dt-bindings/clock/marvell,pxa910.h
+++ b/include/dt-bindings/clock/marvell,pxa910.h
@@ -19,6 +19,7 @@
 #define PXA910_CLK_PLL1_2_1_5  19
 #define PXA910_CLK_PLL1_3_16   20
 #define PXA910_CLK_UART_PLL27
+#define PXA910_CLK_USB_PLL 28
 
 /* apb periphrals */
 #define PXA910_CLK_TWSI0   60
-- 
1.8.3.2

--
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 3/3] clk: mmp: add timer clock for pxa168/mmp2/pxa910

2015-04-07 Thread Chao Xie
From: Chao Xie 

Timer has external fast clock, and it is a mux clock.
Add the timer clock type for timer driver.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-of-mmp2.c  |  6 ++
 drivers/clk/mmp/clk-of-pxa168.c|  7 +++
 drivers/clk/mmp/clk-of-pxa910.c| 11 +++
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  2 ++
 include/dt-bindings/clock/marvell,pxa910.h |  3 +++
 6 files changed, 30 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index b7e0b89..251533d 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -30,6 +30,7 @@
 #define APBC_TWSI4 0x7c
 #define APBC_TWSI5 0x80
 #define APBC_KPC   0x18
+#define APBC_TIMER 0x24
 #define APBC_UART0 0x2c
 #define APBC_UART1 0x30
 #define APBC_UART2 0x34
@@ -132,6 +133,9 @@ static DEFINE_SPINLOCK(ssp2_lock);
 static DEFINE_SPINLOCK(ssp3_lock);
 static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", 
"pll1_16"};
 
+static DEFINE_SPINLOCK(timer_lock);
+static const char *timer_parent_names[] = {"clk32", "vctcxo_2", "vctcxo_4", 
"vctcxo"};
+
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -143,6 +147,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
{0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, _lock},
{0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, _lock},
{0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, _lock},
+   {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), 
CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, _lock},
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -168,6 +173,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
{MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 
0x7, 0x3, 0x0, 0, _lock},
{MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 
0x7, 0x3, 0x0, 0, _lock},
{MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 
0x7, 0x3, 0x0, 0, _lock},
+   {MMP2_CLK_TIMER, "timer_clk", "timer_mux", CLK_SET_RATE_PARENT, 
APBC_TIMER, 0x7, 0x3, 0x0, 0, _lock},
 };
 
 static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 01a650e..64eaf41 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -32,6 +32,7 @@
 #define APBC_PWM1  0x10
 #define APBC_PWM2  0x14
 #define APBC_PWM3  0x18
+#define APBC_TIMER 0x34
 #define APBC_SSP0  0x81c
 #define APBC_SSP1  0x820
 #define APBC_SSP2  0x84c
@@ -71,6 +72,7 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] 
= {
{PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
{PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
{PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
+   {PXA168_CLK_PLL1_192, "pll1_192", "pll1_96", 1, 2, 0},
{PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
{PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
{PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
@@ -120,6 +122,9 @@ static DEFINE_SPINLOCK(ssp3_lock);
 static DEFINE_SPINLOCK(ssp4_lock);
 static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", 
"pll1_12"};
 
+static DEFINE_SPINLOCK(timer_lock);
+static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96", 
"pll1_192"};
+
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -131,6 +136,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
{0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, _lock},
{0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, _lock},
{0, "ssp4_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, _lock},
+   {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), 
CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, _lock},
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -152,6 +158,7 @@ static struct mmp_param_gate_cl

[PATCH 2/3] clk: mmp: Fix the wrong factor table for uart PLL

2015-04-07 Thread Chao Xie
From: Chao Xie 

The suggested value in the mmp2 manual is wrong.
There are only 13 bits for numerator, but some suggested
value has 14 bits.
Fix the factor tabled and remove the unused items.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-mmp2.c| 4 +---
 drivers/clk/mmp/clk-of-mmp2.c | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 5c90a42..09d2832 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -63,10 +63,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
 };
 
 static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
-   {.num = 14634, .den = 2165},/*14.745MHZ */
+   {.num = 8125, .den = 1536}, /*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
-   {.num = 9679, .den = 5728}, /*58.9824MHZ */
-   {.num = 15850, .den = 9451},/*59.429MHZ */
 };
 
 static const char *uart_parent[] = {"uart_pll", "vctcxo"};
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 2cbc2b4..b7e0b89 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -98,10 +98,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
 };
 
 static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
-   {.num = 14634, .den = 2165},/*14.745MHZ */
+   {.num = 8125, .den = 1536}, /*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
-   {.num = 9679, .den = 5728}, /*58.9824MHZ */
-   {.num = 15850, .den = 9451},/*59.429MHZ */
 };
 
 static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
-- 
1.8.3.2

--
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 0/3] clk: mmp: fix and add new clock

2015-04-07 Thread Chao Xie
From: Chao Xie 

There are three patches
First two are fix patches.
The last one will add the timer clock for pxa168/mmp2/pxa910.

The timer driver will make use of the timer clock.

Chao Xie (3):
  clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168
  clk: mmp: Fix the wrong factor table for uart PLL
  clk: mmp: add timer clock for pxa168/mmp2/pxa910

 drivers/clk/mmp/clk-mmp2.c |  4 +---
 drivers/clk/mmp/clk-of-mmp2.c  | 10 +++---
 drivers/clk/mmp/clk-of-pxa168.c|  8 
 drivers/clk/mmp/clk-of-pxa910.c| 12 
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  3 +++
 include/dt-bindings/clock/marvell,pxa910.h |  4 
 7 files changed, 36 insertions(+), 6 deletions(-)

-- 
1.8.3.2

--
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 0/3] clk: mmp: fix and add new clock

2015-04-07 Thread Chao Xie
From: Chao Xie chao@marvell.com

There are three patches
First two are fix patches.
The last one will add the timer clock for pxa168/mmp2/pxa910.

The timer driver will make use of the timer clock.

Chao Xie (3):
  clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168
  clk: mmp: Fix the wrong factor table for uart PLL
  clk: mmp: add timer clock for pxa168/mmp2/pxa910

 drivers/clk/mmp/clk-mmp2.c |  4 +---
 drivers/clk/mmp/clk-of-mmp2.c  | 10 +++---
 drivers/clk/mmp/clk-of-pxa168.c|  8 
 drivers/clk/mmp/clk-of-pxa910.c| 12 
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  3 +++
 include/dt-bindings/clock/marvell,pxa910.h |  4 
 7 files changed, 36 insertions(+), 6 deletions(-)

-- 
1.8.3.2

--
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 1/3] clk: mmp: add fixed clock UBS_PLL for pxa910/pxa168

2015-04-07 Thread Chao Xie
From: Chao Xie chao@marvell.com

USB will drive clock from USB_PLL.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-of-pxa168.c| 1 +
 drivers/clk/mmp/clk-of-pxa910.c| 1 +
 include/dt-bindings/clock/marvell,pxa168.h | 1 +
 include/dt-bindings/clock/marvell,pxa910.h | 1 +
 4 files changed, 4 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 5b1810d..01a650e 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -58,6 +58,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{PXA168_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
{PXA168_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
{PXA168_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 62400},
+   {PXA168_CLK_USB_PLL, usb_pll, NULL, CLK_IS_ROOT, 48000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
index 5e3c80d..cca98ef 100644
--- a/drivers/clk/mmp/clk-of-pxa910.c
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -57,6 +57,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{PXA910_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
{PXA910_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
{PXA910_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 62400},
+   {PXA910_CLK_USB_PLL, usb_pll, NULL, CLK_IS_ROOT, 48000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/include/dt-bindings/clock/marvell,pxa168.h 
b/include/dt-bindings/clock/marvell,pxa168.h
index 79630b9..84ce5de 100644
--- a/include/dt-bindings/clock/marvell,pxa168.h
+++ b/include/dt-bindings/clock/marvell,pxa168.h
@@ -19,6 +19,7 @@
 #define PXA168_CLK_PLL1_2_1_5  19
 #define PXA168_CLK_PLL1_3_16   20
 #define PXA168_CLK_UART_PLL27
+#define PXA168_CLK_USB_PLL 28
 
 /* apb periphrals */
 #define PXA168_CLK_TWSI0   60
diff --git a/include/dt-bindings/clock/marvell,pxa910.h 
b/include/dt-bindings/clock/marvell,pxa910.h
index 719cffb..bea08b6 100644
--- a/include/dt-bindings/clock/marvell,pxa910.h
+++ b/include/dt-bindings/clock/marvell,pxa910.h
@@ -19,6 +19,7 @@
 #define PXA910_CLK_PLL1_2_1_5  19
 #define PXA910_CLK_PLL1_3_16   20
 #define PXA910_CLK_UART_PLL27
+#define PXA910_CLK_USB_PLL 28
 
 /* apb periphrals */
 #define PXA910_CLK_TWSI0   60
-- 
1.8.3.2

--
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 3/3] clk: mmp: add timer clock for pxa168/mmp2/pxa910

2015-04-07 Thread Chao Xie
From: Chao Xie chao@marvell.com

Timer has external fast clock, and it is a mux clock.
Add the timer clock type for timer driver.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-of-mmp2.c  |  6 ++
 drivers/clk/mmp/clk-of-pxa168.c|  7 +++
 drivers/clk/mmp/clk-of-pxa910.c| 11 +++
 include/dt-bindings/clock/marvell,mmp2.h   |  1 +
 include/dt-bindings/clock/marvell,pxa168.h |  2 ++
 include/dt-bindings/clock/marvell,pxa910.h |  3 +++
 6 files changed, 30 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index b7e0b89..251533d 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -30,6 +30,7 @@
 #define APBC_TWSI4 0x7c
 #define APBC_TWSI5 0x80
 #define APBC_KPC   0x18
+#define APBC_TIMER 0x24
 #define APBC_UART0 0x2c
 #define APBC_UART1 0x30
 #define APBC_UART2 0x34
@@ -132,6 +133,9 @@ static DEFINE_SPINLOCK(ssp2_lock);
 static DEFINE_SPINLOCK(ssp3_lock);
 static const char *ssp_parent_names[] = {vctcxo_4, vctcxo_2, vctcxo, 
pll1_16};
 
+static DEFINE_SPINLOCK(timer_lock);
+static const char *timer_parent_names[] = {clk32, vctcxo_2, vctcxo_4, 
vctcxo};
+
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -143,6 +147,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
{0, ssp1_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, ssp1_lock},
{0, ssp2_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, ssp2_lock},
{0, ssp3_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, ssp3_lock},
+   {0, timer_mux, timer_parent_names, ARRAY_SIZE(timer_parent_names), 
CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, timer_lock},
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -168,6 +173,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
{MMP2_CLK_SSP1, ssp1_clk, ssp1_mux, CLK_SET_RATE_PARENT, APBC_SSP1, 
0x7, 0x3, 0x0, 0, ssp1_lock},
{MMP2_CLK_SSP2, ssp2_clk, ssp2_mux, CLK_SET_RATE_PARENT, APBC_SSP2, 
0x7, 0x3, 0x0, 0, ssp2_lock},
{MMP2_CLK_SSP3, ssp3_clk, ssp3_mux, CLK_SET_RATE_PARENT, APBC_SSP3, 
0x7, 0x3, 0x0, 0, ssp3_lock},
+   {MMP2_CLK_TIMER, timer_clk, timer_mux, CLK_SET_RATE_PARENT, 
APBC_TIMER, 0x7, 0x3, 0x0, 0, timer_lock},
 };
 
 static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 01a650e..64eaf41 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -32,6 +32,7 @@
 #define APBC_PWM1  0x10
 #define APBC_PWM2  0x14
 #define APBC_PWM3  0x18
+#define APBC_TIMER 0x34
 #define APBC_SSP0  0x81c
 #define APBC_SSP1  0x820
 #define APBC_SSP2  0x84c
@@ -71,6 +72,7 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] 
= {
{PXA168_CLK_PLL1_24, pll1_24, pll1_12, 1, 2, 0},
{PXA168_CLK_PLL1_48, pll1_48, pll1_24, 1, 2, 0},
{PXA168_CLK_PLL1_96, pll1_96, pll1_48, 1, 2, 0},
+   {PXA168_CLK_PLL1_192, pll1_192, pll1_96, 1, 2, 0},
{PXA168_CLK_PLL1_13, pll1_13, pll1, 1, 13, 0},
{PXA168_CLK_PLL1_13_1_5, pll1_13_1_5, pll1_13, 2, 3, 0},
{PXA168_CLK_PLL1_2_1_5, pll1_2_1_5, pll1_2, 2, 3, 0},
@@ -120,6 +122,9 @@ static DEFINE_SPINLOCK(ssp3_lock);
 static DEFINE_SPINLOCK(ssp4_lock);
 static const char *ssp_parent_names[] = {pll1_96, pll1_48, pll1_24, 
pll1_12};
 
+static DEFINE_SPINLOCK(timer_lock);
+static const char *timer_parent_names[] = {pll1_48, clk32, pll1_96, 
pll1_192};
+
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -131,6 +136,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
{0, ssp2_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, ssp2_lock},
{0, ssp3_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, ssp3_lock},
{0, ssp4_mux, ssp_parent_names, ARRAY_SIZE(ssp_parent_names), 
CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, ssp4_lock},
+   {0, timer_mux, timer_parent_names, ARRAY_SIZE(timer_parent_names), 
CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, timer_lock},
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -152,6 +158,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
{PXA168_CLK_SSP2, ssp2_clk, ssp2_mux, CLK_SET_RATE_PARENT, 
APBC_SSP2, 0x3, 0x3, 0x0, 0, ssp2_lock},
{PXA168_CLK_SSP3, ssp3_clk, ssp3_mux, CLK_SET_RATE_PARENT, 
APBC_SSP3, 0x3, 0x3, 0x0, 0, ssp3_lock},
{PXA168_CLK_SSP4, ssp4_clk, ssp4_mux, CLK_SET_RATE_PARENT, 
APBC_SSP4, 0x3, 0x3, 0x0, 0, ssp4_lock},
+   {PXA168_CLK_TIMER, timer_clk, timer_mux, CLK_SET_RATE_PARENT, 
APBC_TIMER, 0x3, 0x3, 0x0, 0, timer_lock

[PATCH 2/3] clk: mmp: Fix the wrong factor table for uart PLL

2015-04-07 Thread Chao Xie
From: Chao Xie chao@marvell.com

The suggested value in the mmp2 manual is wrong.
There are only 13 bits for numerator, but some suggested
value has 14 bits.
Fix the factor tabled and remove the unused items.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-mmp2.c| 4 +---
 drivers/clk/mmp/clk-of-mmp2.c | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 5c90a42..09d2832 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -63,10 +63,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
 };
 
 static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
-   {.num = 14634, .den = 2165},/*14.745MHZ */
+   {.num = 8125, .den = 1536}, /*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
-   {.num = 9679, .den = 5728}, /*58.9824MHZ */
-   {.num = 15850, .den = 9451},/*59.429MHZ */
 };
 
 static const char *uart_parent[] = {uart_pll, vctcxo};
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 2cbc2b4..b7e0b89 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -98,10 +98,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
 };
 
 static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
-   {.num = 14634, .den = 2165},/*14.745MHZ */
+   {.num = 8125, .den = 1536}, /*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
-   {.num = 9679, .den = 5728}, /*58.9824MHZ */
-   {.num = 15850, .den = 9451},/*59.429MHZ */
 };
 
 static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
-- 
1.8.3.2

--
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:Re: [PATCH V2] gpio: mmp: add GPIO driver for Marvell MMP series

2015-03-17 Thread Chao Xie


At 2015-03-17 18:25:24, "Linus Walleij"  wrote:
>On Fri, Mar 6, 2015 at 3:04 AM, Chao Xie  wrote:
>
>> Signed-off-by: Chao Xie 
>
>First can some of the MMP people comment on this driver please?
>(Eric/Haojian)
>
>So this driver duplicates drivers/gpio/gpio-pxa.c in some sense but
>is nicer and cleaner and thus an incentive for me to merge it.
>At the same time I don't want two drivers for essentially the same
>hardware and in that way I would prefer to clean up the PXA driver.
>
>But I don't know how close the PXA and MMP drivers really are.
>
>Will it also cover MMP2 that is currently using by the PXA driver?
>
>Is it really complicated to migrate gpio-pxa to GPIOLIB_IRQCHIP?
>
>I guess you should also delete the compatible string and
>compatibility code in drivers/gpio/gpio-pxa.c (as a separate patch
>in this series) and merge this along with some defconfig
>changes that activates this by default for the MMP machines?

>


I will ask Haojian to comment at it when send out V3 patch.
pxa and mmp are two different series.
First pxa is Intel's product, and after Intel sell its xscale to marvell, the 
SOC series become mmp.
The SOC design has many differences.
now mmp gpio has some registers kept in order to use the old pxa driver, but 
silicon designer
warned us that it is better to use the new register interfaces.
The major differences are:
For all the edge detecting setting/clearing, level setting/clearing, direction 
setting/clearing, mmp has
separated registers

>> +config GPIO_MMP
>> +   bool "MMP GPIO support"
>> +   depends on ARCH_MMP
>> +   select GPIOLIB_IRQCHIP
>
>NICE!
>
>> +struct mmp_gpio_bank {
>> +   void __iomem *reg_bank;
>> +   u32 irq_mask;
>> +   u32 irq_rising_edge;
>> +   u32 irq_falling_edge;
>
>I can't see why you're keeping all these settings of the edges and mask
>in these variables. Why can't you just keep the state in the hardware
>registers?

>
When other driver request gpio, it will set whether it is rising edge detect or
falling edge detect or both.
We need record it.
So when user mask/unmask the interrupt, we know whether we need clear/set
rising edge detect/falling edge detect or both.

>> +};
>> +
>> +struct mmp_gpio_chip {
>> +   struct gpio_chip chip;
>> +   void __iomem *reg_base;
>> +   int irq;
>
>Do you need to keep irq around if you use devm_* to request the
>IRQ?

>


Yes, it is right. I will remove it.

>> +   unsigned int ngpio;
>
>This is already stored in struct gpio_chip, why
>store it a second time in this struct?
>
>> +   unsigned int nbank;
>> +   struct mmp_gpio_bank *banks;
>
>To repeat an eternal story: why do you have to register several
>banks under the same gpio_chip? I guess it's because they share
>a single IRQ line, but wanna make sure

>
Yes. they share same interrupt line.

There are the following reasons
1. There is only one IRQ for the whole GPIO, even there are 3 or more banks.
2. The registers are not formatted into group. They are interleaved.
 For example, there are three banks, So for the registers order are
 LEVEL_STATUS_BANK0, LEVEL_STASTUS_BANK1, LEVEL_STATUS_BANK2
 DIRECTION_STATUS_BANK0, DIRECTION_STATUS_BANK1, DIRECTION_STATUS_BANK2
>> +};>> +
>> +static int mmp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
>> +{
>> +   struct mmp_gpio_chip *mmp_chip =
>> +   container_of(chip, struct mmp_gpio_chip, chip);
>> +   struct mmp_gpio_bank *bank =
>> +   _chip->banks[mmp_gpio_to_bank_idx(offset)];
>
>Rewrite this:
>
>> +   u32 bit = (1 << mmp_gpio_to_bank_offset(offset));
>> +
>> +   writel(bit, bank->reg_bank + GCDR);
>
>Like this:
>
>#include 
>
>writel(BIT(mmp_gpio_to_bank_offset(offset)), bank->reg_bank + GCDR);

>
I will do it.>
>> +static int mmp_gpio_direction_output(struct gpio_chip *chip,
>> +unsigned offset, int value)
>> +{
>
>Use the same pattern with BIT() as described above.

>
I will do it.>> +static int mmp_gpio_get(struct gpio_chip *chip, unsigned 
offset)
>> +{
>> +
>> +   return !!(gplr & bit);
>
>Use the same pattern with BIT() as described above.

>


I will do it.
I will use BIT() for all below comments you suggested. Thanks.>> +static struct 
irq_chip mmp_muxed_gpio_chip = {
>> +   .name   = "mmp-gpio-irqchip",
>> +   .irq_mask   = mmp_mask_muxed_gpio,
>> +   .irq_unmask = mmp_unmask_muxed_gpio,
>> +   .irq_set_t

Re:Re: [PATCH V2] gpio: mmp: add GPIO driver for Marvell MMP series

2015-03-17 Thread Chao Xie


At 2015-03-17 18:25:24, Linus Walleij linus.wall...@linaro.org wrote:
On Fri, Mar 6, 2015 at 3:04 AM, Chao Xie chao@marvell.com wrote:

 Signed-off-by: Chao Xie chao@marvell.com

First can some of the MMP people comment on this driver please?
(Eric/Haojian)

So this driver duplicates drivers/gpio/gpio-pxa.c in some sense but
is nicer and cleaner and thus an incentive for me to merge it.
At the same time I don't want two drivers for essentially the same
hardware and in that way I would prefer to clean up the PXA driver.

But I don't know how close the PXA and MMP drivers really are.

Will it also cover MMP2 that is currently using by the PXA driver?

Is it really complicated to migrate gpio-pxa to GPIOLIB_IRQCHIP?

I guess you should also delete the compatible string and
compatibility code in drivers/gpio/gpio-pxa.c (as a separate patch
in this series) and merge this along with some defconfig
changes that activates this by default for the MMP machines?




I will ask Haojian to comment at it when send out V3 patch.
pxa and mmp are two different series.
First pxa is Intel's product, and after Intel sell its xscale to marvell, the 
SOC series become mmp.
The SOC design has many differences.
now mmp gpio has some registers kept in order to use the old pxa driver, but 
silicon designer
warned us that it is better to use the new register interfaces.
The major differences are:
For all the edge detecting setting/clearing, level setting/clearing, direction 
setting/clearing, mmp has
separated registers

 +config GPIO_MMP
 +   bool MMP GPIO support
 +   depends on ARCH_MMP
 +   select GPIOLIB_IRQCHIP

NICE!

 +struct mmp_gpio_bank {
 +   void __iomem *reg_bank;
 +   u32 irq_mask;
 +   u32 irq_rising_edge;
 +   u32 irq_falling_edge;

I can't see why you're keeping all these settings of the edges and mask
in these variables. Why can't you just keep the state in the hardware
registers?


When other driver request gpio, it will set whether it is rising edge detect or
falling edge detect or both.
We need record it.
So when user mask/unmask the interrupt, we know whether we need clear/set
rising edge detect/falling edge detect or both.

 +};
 +
 +struct mmp_gpio_chip {
 +   struct gpio_chip chip;
 +   void __iomem *reg_base;
 +   int irq;

Do you need to keep irq around if you use devm_* to request the
IRQ?




Yes, it is right. I will remove it.

 +   unsigned int ngpio;

This is already stored in struct gpio_chip, why
store it a second time in this struct?

 +   unsigned int nbank;
 +   struct mmp_gpio_bank *banks;

To repeat an eternal story: why do you have to register several
banks under the same gpio_chip? I guess it's because they share
a single IRQ line, but wanna make sure


Yes. they share same interrupt line.

There are the following reasons
1. There is only one IRQ for the whole GPIO, even there are 3 or more banks.
2. The registers are not formatted into group. They are interleaved.
 For example, there are three banks, So for the registers order are
 LEVEL_STATUS_BANK0, LEVEL_STASTUS_BANK1, LEVEL_STATUS_BANK2
 DIRECTION_STATUS_BANK0, DIRECTION_STATUS_BANK1, DIRECTION_STATUS_BANK2
 +}; +
 +static int mmp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 +{
 +   struct mmp_gpio_chip *mmp_chip =
 +   container_of(chip, struct mmp_gpio_chip, chip);
 +   struct mmp_gpio_bank *bank =
 +   mmp_chip-banks[mmp_gpio_to_bank_idx(offset)];

Rewrite this:

 +   u32 bit = (1  mmp_gpio_to_bank_offset(offset));
 +
 +   writel(bit, bank-reg_bank + GCDR);

Like this:

#include linux/bitops.h

writel(BIT(mmp_gpio_to_bank_offset(offset)), bank-reg_bank + GCDR);


I will do it.
 +static int mmp_gpio_direction_output(struct gpio_chip *chip,
 +unsigned offset, int value)
 +{

Use the same pattern with BIT() as described above.


I will do it. +static int mmp_gpio_get(struct gpio_chip *chip, unsigned 
offset)
 +{
 +
 +   return !!(gplr  bit);

Use the same pattern with BIT() as described above.




I will do it.
I will use BIT() for all below comments you suggested. Thanks. +static struct 
irq_chip mmp_muxed_gpio_chip = {
 +   .name   = mmp-gpio-irqchip,
 +   .irq_mask   = mmp_mask_muxed_gpio,
 +   .irq_unmask = mmp_unmask_muxed_gpio,
 +   .irq_set_type   = mmp_gpio_irq_type,
 +   .flags  = IRQCHIP_SKIP_SET_WAKE,
 +};
 +
 +static struct of_device_id mmp_gpio_dt_ids[] = {
 +   { .compatible = marvell,mmp-gpio},
 +   {}
 +};

So the same functionality in the other compatible driver should
be deleted as a separate patch.




Yes. a separated patch is needed.

 +static int mmp_gpio_probe_dt(struct platform_device *pdev,
 +   struct mmp_gpio_chip *mmp_chip)
 +{
 +   struct device_node *np = pdev-dev.of_node;
 +   struct device_node *child;
 +   u32 offset

[PATCH V2] gpio: mmp: add GPIO driver for Marvell MMP series

2015-03-05 Thread Chao Xie
From: Chao Xie 

For some old PXA series, they used PXA GPIO driver.
The IP of GPIO changes since PXA988 which is Marvell MMP
series.
It will use new way to control the GPIO level, direction
and edge status.

Signed-off-by: Chao Xie 
---
 drivers/gpio/Kconfig|  10 ++
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-mmp.c | 364 
 3 files changed, 375 insertions(+)
 create mode 100644 drivers/gpio/gpio-mmp.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 633ec21..6dce470 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -197,6 +197,16 @@ config GPIO_F7188X
  To compile this driver as a module, choose M here: the module will
  be called f7188x-gpio.
 
+config GPIO_MMP
+   bool "MMP GPIO support"
+   depends on ARCH_MMP
+   select GPIOLIB_IRQCHIP
+   help
+ Say yes here to support the MMP GPIO device at
+ PXA1088/PXA1908/PXA1928. Comparing with PXA GPIO device, the IP of
+ MMP GPIO changes a lot. It will use new way to control the GPIO
+ level, direction and edge status.
+
 config GPIO_MOXART
bool "MOXART GPIO support"
depends on ARCH_MOXART
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 81755f1..60a7cf5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
 obj-$(CONFIG_GPIO_MCP23S08)+= gpio-mcp23s08.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
+obj-$(CONFIG_GPIO_MMP) += gpio-mmp.o
 obj-$(CONFIG_GPIO_MOXART)  += gpio-moxart.o
 obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
diff --git a/drivers/gpio/gpio-mmp.c b/drivers/gpio/gpio-mmp.c
new file mode 100644
index 000..4202654
--- /dev/null
+++ b/drivers/gpio/gpio-mmp.c
@@ -0,0 +1,364 @@
+/*
+ *  Copyright (C) 2015 Marvell International Ltd.
+ *
+ *  Generic MMP GPIO handling
+ *
+ * Chao Xie 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define GPLR   0x0
+#define GPDR   0xc
+#define GPSR   0x18
+#define GPCR   0x24
+#define GRER   0x30
+#define GFER   0x3c
+#define GEDR   0x48
+#define GSDR   0x54
+#define GCDR   0x60
+#define GSRER  0x6c
+#define GCRER  0x78
+#define GSFER  0x84
+#define GCFER  0x90
+#define GAPMASK0x9c
+#define GCPMASK0xa8
+
+/* Bank will have 2^n GPIOes, and for mmp-gpio n = 5 */
+#define BANK_GPIO_ORDER5
+#define BANK_GPIO_NUMBER   (1 << BANK_GPIO_ORDER)
+#define BANK_GPIO_MASK (BANK_GPIO_NUMBER - 1)
+
+#define mmp_gpio_to_bank_idx(gpio) ((gpio) >> BANK_GPIO_ORDER)
+#define mmp_gpio_to_bank_offset(gpio)  ((gpio) & BANK_GPIO_MASK)
+#define mmp_bank_to_gpio(idx, offset)  (((idx) << BANK_GPIO_ORDER) \
+   | ((offset) & BANK_GPIO_MASK))
+
+struct mmp_gpio_bank {
+   void __iomem *reg_bank;
+   u32 irq_mask;
+   u32 irq_rising_edge;
+   u32 irq_falling_edge;
+};
+
+struct mmp_gpio_chip {
+   struct gpio_chip chip;
+   void __iomem *reg_base;
+   int irq;
+   unsigned int ngpio;
+   unsigned int nbank;
+   struct mmp_gpio_bank *banks;
+};
+
+static int mmp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   _chip->banks[mmp_gpio_to_bank_idx(offset)];
+   u32 bit = (1 << mmp_gpio_to_bank_offset(offset));
+
+   writel(bit, bank->reg_bank + GCDR);
+
+   return 0;
+}
+
+static int mmp_gpio_direction_output(struct gpio_chip *chip,
+unsigned offset, int value)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   _chip->banks[mmp_gpio_to_bank_idx(offset)];
+   u32 bit = (1 << mmp_gpio_to_bank_offset(offset));
+
+   /* Set value first. */
+   writel(bit, bank->reg_bank + (value ? GPSR : GPCR));
+
+   writel(bit, bank->reg_bank + GSDR);
+
+   return 0;
+}
+
+static int mmp_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   _chip->banks[mmp_gpio_to_bank_idx(offset)]

[PATCH V2] gpio: mmp: add GPIO driver for Marvell MMP series

2015-03-05 Thread Chao Xie
From: Chao Xie chao@marvell.com

For some old PXA series, they used PXA GPIO driver.
The IP of GPIO changes since PXA988 which is Marvell MMP
series.
It will use new way to control the GPIO level, direction
and edge status.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/gpio/Kconfig|  10 ++
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-mmp.c | 364 
 3 files changed, 375 insertions(+)
 create mode 100644 drivers/gpio/gpio-mmp.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 633ec21..6dce470 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -197,6 +197,16 @@ config GPIO_F7188X
  To compile this driver as a module, choose M here: the module will
  be called f7188x-gpio.
 
+config GPIO_MMP
+   bool MMP GPIO support
+   depends on ARCH_MMP
+   select GPIOLIB_IRQCHIP
+   help
+ Say yes here to support the MMP GPIO device at
+ PXA1088/PXA1908/PXA1928. Comparing with PXA GPIO device, the IP of
+ MMP GPIO changes a lot. It will use new way to control the GPIO
+ level, direction and edge status.
+
 config GPIO_MOXART
bool MOXART GPIO support
depends on ARCH_MOXART
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 81755f1..60a7cf5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
 obj-$(CONFIG_GPIO_MCP23S08)+= gpio-mcp23s08.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
+obj-$(CONFIG_GPIO_MMP) += gpio-mmp.o
 obj-$(CONFIG_GPIO_MOXART)  += gpio-moxart.o
 obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
diff --git a/drivers/gpio/gpio-mmp.c b/drivers/gpio/gpio-mmp.c
new file mode 100644
index 000..4202654
--- /dev/null
+++ b/drivers/gpio/gpio-mmp.c
@@ -0,0 +1,364 @@
+/*
+ *  Copyright (C) 2015 Marvell International Ltd.
+ *
+ *  Generic MMP GPIO handling
+ *
+ * Chao Xie chao@marvell.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/gpio/driver.h
+#include linux/clk.h
+#include linux/of_device.h
+#include linux/platform_device.h
+
+#define GPLR   0x0
+#define GPDR   0xc
+#define GPSR   0x18
+#define GPCR   0x24
+#define GRER   0x30
+#define GFER   0x3c
+#define GEDR   0x48
+#define GSDR   0x54
+#define GCDR   0x60
+#define GSRER  0x6c
+#define GCRER  0x78
+#define GSFER  0x84
+#define GCFER  0x90
+#define GAPMASK0x9c
+#define GCPMASK0xa8
+
+/* Bank will have 2^n GPIOes, and for mmp-gpio n = 5 */
+#define BANK_GPIO_ORDER5
+#define BANK_GPIO_NUMBER   (1  BANK_GPIO_ORDER)
+#define BANK_GPIO_MASK (BANK_GPIO_NUMBER - 1)
+
+#define mmp_gpio_to_bank_idx(gpio) ((gpio)  BANK_GPIO_ORDER)
+#define mmp_gpio_to_bank_offset(gpio)  ((gpio)  BANK_GPIO_MASK)
+#define mmp_bank_to_gpio(idx, offset)  (((idx)  BANK_GPIO_ORDER) \
+   | ((offset)  BANK_GPIO_MASK))
+
+struct mmp_gpio_bank {
+   void __iomem *reg_bank;
+   u32 irq_mask;
+   u32 irq_rising_edge;
+   u32 irq_falling_edge;
+};
+
+struct mmp_gpio_chip {
+   struct gpio_chip chip;
+   void __iomem *reg_base;
+   int irq;
+   unsigned int ngpio;
+   unsigned int nbank;
+   struct mmp_gpio_bank *banks;
+};
+
+static int mmp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   mmp_chip-banks[mmp_gpio_to_bank_idx(offset)];
+   u32 bit = (1  mmp_gpio_to_bank_offset(offset));
+
+   writel(bit, bank-reg_bank + GCDR);
+
+   return 0;
+}
+
+static int mmp_gpio_direction_output(struct gpio_chip *chip,
+unsigned offset, int value)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   mmp_chip-banks[mmp_gpio_to_bank_idx(offset)];
+   u32 bit = (1  mmp_gpio_to_bank_offset(offset));
+
+   /* Set value first. */
+   writel(bit, bank-reg_bank + (value ? GPSR : GPCR));
+
+   writel(bit, bank-reg_bank + GSDR);
+
+   return 0;
+}
+
+static int mmp_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank

Re:Re: [PATCH] gpio: mmp: add GPIO driver for Marvell MMP series

2015-02-03 Thread Chao Xie

At 2015-02-03 21:21:43, "Linus Walleij"  wrote:
>On Wed, Jan 28, 2015 at 3:30 AM, Chao Xie  wrote:
>
>> From: Chao Xie 
>>
>> For some old PXA series, they used PXA GPIO driver.
>> The IP of GPIO changes since PXA988 which is Marvell MMP
>> series.
>> It will use new way to control the GPIO level, direction
>> and edge status.
>>
>> Signed-off-by: Chao Xie 
>
>(...)
>
>> +config GPIO_MMP
>> +   bool "MMP GPIO support"
>> +   depends on ARCH_MMP
>
>All new simple drivers with IRQ should
>
>select GPIOLIB_IRQCHIP
>

Thanks for review.

I will check GPIOLIB_IRQCHIP and make use of it.

>Since this looks like a basic MMIO driver I think
>you should also use:
>
>select GPIO_GENERIC
>

I think the gpio-mmp is not same as gpio-generic.
gpio-mmp need control the level/direction/rising edge detect enable/falling 
edge detect enable.
For each of them, there are three registers: status register,  setting register 
and clear register.
For example, for direction, if you configure it as output.
You need SET the bit in setting register.
If you want to configure it as input
You need SET the bit in clear register.
The bits will be cleared by hardware if the operation is completed by hardware.

It is same for level/rising edege detect enable/falling edge detect enable.

If you want to read the status of the pin. For example, the current level of 
the pin.
You CAN NOT read the setting/clear register. You need read the level status 
register.

>And set up simple getter/setter functions with a
>
>
>> +   help
>> + Say yes here to support the MMP GPIO device at 
>> PXA1088/PXA1908/PXA1928.
>> + Comparing with PXA GPIO device, the IP of MMP GPIO changes a lot.
>> +
>
>(...)
>
>> +++ b/drivers/gpio/gpio-mmp.c
>
>> +#include 
>> +#include 
>> +#include 
>
>You don't need this include with GPIOLIB_IRQCHIP
>

I will fix it.

>> +#include 
>> +#include 
>> +#include 
>
>#include 
>
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>
>get rid of these two includes in favor of using GPIOLIB_IRQCHIP
>

I will fix it.

>> +#include 
>
>Add:
>#include 
>
>And implement generic GPIO using bgpio_init()
>
>(...)

The reasons are listed above

>> +#define GPLR   0x0
>> +#define GPDR   0xc
>> +#define GPSR   0x18
>> +#define GPCR   0x24
>> +#define GRER   0x30
>> +#define GFER   0x3c
>> +#define GEDR   0x48
>> +#define GSDR   0x54
>> +#define GCDR   0x60
>> +#define GSRER  0x6c
>> +#define GCRER  0x78
>> +#define GSFER  0x84
>> +#define GCFER  0x90
>> +#define GAPMASK0x9c
>> +#define GCPMASK0xa8
>> +
>> +/* Bank will have 2^n GPIOes, and for mmp-gpio n = 5 */
>> +#define BANK_GPIO_ORDER5
>> +#define BANK_GPIO_NUMBER   (1 << BANK_GPIO_ORDER)
>> +#define BANK_GPIO_MASK (BANK_GPIO_NUMBER - 1)
>> +
>> +#define mmp_gpio_to_bank_idx(gpio) ((gpio) >> BANK_GPIO_ORDER)
>> +#define mmp_gpio_to_bank_offset(gpio)  ((gpio) & BANK_GPIO_MASK)
>> +#define mmp_bank_to_gpio(idx, offset)  (((idx) << BANK_GPIO_ORDER) \
>> +   | ((offset) & 
>> BANK_GPIO_MASK))
>> +
>
>This looks convoluted. Why not just register each bank as a separate
>device instead of trying to figure out bank index like this?
>

There are the following reasons
1. There is only one IRQ for the whole GPIO, even there are 3 or more banks.
2. The registers are not formatted into group. They are interleaved.
For example, there are three banks, So for the registers order are
LEVEL_STATUS_BANK0, LEVEL_STASTUS_BANK1, LEVEL_STATUS_BANK2
DIRECTION_STATUS_BANK0, DIRECTION_STATUS_BANK1, DIRECTION_STATUS_BANK2
3. each bank has 32 bits. Formatting them into one driver will make other 
driver easier.
For example, the MMC driver has GPIO detection for card. So it knows the 
GPIO is GPIO56.
In the device tree of MMC driver, you can simple add as
cd-gpios = < 56 X>
if you format them into different devices, the mmc driver owner need to 
know how much bits a bank is, and calculate out correct GPIOx and offset
cd-gpios = < 24 X>

>> +struct mmp_gpio_bank {
>> +   void __iomem *reg_bank;
>> +   u32 irq_mask;
>> +   u32 irq_rising_edge;
>> +   u32 irq_falling_edge;
>> +};
>> +
>> +struct mmp_gpio_chip {
>> +   

Re:Re: [PATCH] gpio: mmp: add GPIO driver for Marvell MMP series

2015-02-03 Thread Chao Xie

At 2015-02-03 21:21:43, Linus Walleij linus.wall...@linaro.org wrote:
On Wed, Jan 28, 2015 at 3:30 AM, Chao Xie chao@marvell.com wrote:

 From: Chao Xie chao@marvell.com

 For some old PXA series, they used PXA GPIO driver.
 The IP of GPIO changes since PXA988 which is Marvell MMP
 series.
 It will use new way to control the GPIO level, direction
 and edge status.

 Signed-off-by: Chao Xie chao@marvell.com

(...)

 +config GPIO_MMP
 +   bool MMP GPIO support
 +   depends on ARCH_MMP

All new simple drivers with IRQ should

select GPIOLIB_IRQCHIP


Thanks for review.

I will check GPIOLIB_IRQCHIP and make use of it.

Since this looks like a basic MMIO driver I think
you should also use:

select GPIO_GENERIC


I think the gpio-mmp is not same as gpio-generic.
gpio-mmp need control the level/direction/rising edge detect enable/falling 
edge detect enable.
For each of them, there are three registers: status register,  setting register 
and clear register.
For example, for direction, if you configure it as output.
You need SET the bit in setting register.
If you want to configure it as input
You need SET the bit in clear register.
The bits will be cleared by hardware if the operation is completed by hardware.

It is same for level/rising edege detect enable/falling edge detect enable.

If you want to read the status of the pin. For example, the current level of 
the pin.
You CAN NOT read the setting/clear register. You need read the level status 
register.

And set up simple getter/setter functions with a


 +   help
 + Say yes here to support the MMP GPIO device at 
 PXA1088/PXA1908/PXA1928.
 + Comparing with PXA GPIO device, the IP of MMP GPIO changes a lot.
 +

(...)

 +++ b/drivers/gpio/gpio-mmp.c

 +#include linux/err.h
 +#include linux/init.h
 +#include linux/irq.h

You don't need this include with GPIOLIB_IRQCHIP


I will fix it.

 +#include linux/interrupt.h
 +#include linux/io.h
 +#include linux/gpio.h

#include linux/gpio/driver.h

 +#include linux/clk.h
 +#include linux/of_device.h
 +#include linux/platform_device.h
 +#include linux/module.h
 +#include linux/irqdomain.h
 +#include linux/irqchip/chained_irq.h

get rid of these two includes in favor of using GPIOLIB_IRQCHIP


I will fix it.

 +#include linux/platform_data/gpio-mmp.h

Add:
#include linux/basic_mmio_gpio.h

And implement generic GPIO using bgpio_init()

(...)

The reasons are listed above

 +#define GPLR   0x0
 +#define GPDR   0xc
 +#define GPSR   0x18
 +#define GPCR   0x24
 +#define GRER   0x30
 +#define GFER   0x3c
 +#define GEDR   0x48
 +#define GSDR   0x54
 +#define GCDR   0x60
 +#define GSRER  0x6c
 +#define GCRER  0x78
 +#define GSFER  0x84
 +#define GCFER  0x90
 +#define GAPMASK0x9c
 +#define GCPMASK0xa8
 +
 +/* Bank will have 2^n GPIOes, and for mmp-gpio n = 5 */
 +#define BANK_GPIO_ORDER5
 +#define BANK_GPIO_NUMBER   (1  BANK_GPIO_ORDER)
 +#define BANK_GPIO_MASK (BANK_GPIO_NUMBER - 1)
 +
 +#define mmp_gpio_to_bank_idx(gpio) ((gpio)  BANK_GPIO_ORDER)
 +#define mmp_gpio_to_bank_offset(gpio)  ((gpio)  BANK_GPIO_MASK)
 +#define mmp_bank_to_gpio(idx, offset)  (((idx)  BANK_GPIO_ORDER) \
 +   | ((offset)  
 BANK_GPIO_MASK))
 +

This looks convoluted. Why not just register each bank as a separate
device instead of trying to figure out bank index like this?


There are the following reasons
1. There is only one IRQ for the whole GPIO, even there are 3 or more banks.
2. The registers are not formatted into group. They are interleaved.
For example, there are three banks, So for the registers order are
LEVEL_STATUS_BANK0, LEVEL_STASTUS_BANK1, LEVEL_STATUS_BANK2
DIRECTION_STATUS_BANK0, DIRECTION_STATUS_BANK1, DIRECTION_STATUS_BANK2
3. each bank has 32 bits. Formatting them into one driver will make other 
driver easier.
For example, the MMC driver has GPIO detection for card. So it knows the 
GPIO is GPIO56.
In the device tree of MMC driver, you can simple add as
cd-gpios = gpio 56 X
if you format them into different devices, the mmc driver owner need to 
know how much bits a bank is, and calculate out correct GPIOx and offset
cd-gpios = gpio1 24 X

 +struct mmp_gpio_bank {
 +   void __iomem *reg_bank;
 +   u32 irq_mask;
 +   u32 irq_rising_edge;
 +   u32 irq_falling_edge;
 +};
 +
 +struct mmp_gpio_chip {
 +   struct gpio_chip chip;

That should then be
struct bgpio_chip   bgc;

For generic GPIO.

 +   void __iomem *reg_base;
 +   int irq;
 +   struct irq_domain *domain;

These two will not be necessary to keep around with
GPIOLIB_IRQCHIP

 +   unsigned int ngpio;

This is part of struct gpio_chip so do not duplicate it.

 +   unsigned int nbank;
 +   struct mmp_gpio_bank *banks;

And those two I think you

Re: [PATCH 1/4] clocksource: mmp: add mmp timer driver

2015-02-02 Thread Chao Xie



>From: Mark Rutland [mailto:mark.rutl...@arm.com] 
>Sent: 2015年2月2日 18:35
>To: Chao Xie
>Cc: daniel.lezc...@linaro.org; t...@linutronix.de; haojian.zhu...@linaro.org; 
>linux-kernel@vger.kernel.org; devicet...@vger.kernel.org
>Subject: Re: [PATCH 1/4] clocksource: mmp: add mmp timer driver
>
>On Mon, Feb 02, 2015 at 08:31:36AM +, Chao Xie wrote:
>> From: Chao Xie 
>> 
>> MMP timer is attached to APB bus, It has the following limitation.
>> 1. When get count of timer counter, it need some delay
>>to get a stable count.
>> 2. When set match register, it need disable the counter
>>first, and enable it after set the match register.
>>The disabling need wait for 2 clock cycle to take
>>effect.
>> 
>> To improve above #1, shadow register for count is added.
>> To improve above #2, CRSR register is added for quick updating.
>> 
>> So there are three types of timer.
>> timer1: old timer.
>> timer2: old timer with shadow register.
>> timer3: old timer with shadow and CRSR register.
>> 
>> This timer driver will be used for many SOCes.
>> 1. pxa168, pxa910, pxa988 pxa1088 have only timer1.
>> 2. pxa1L88, pxa1U88 have timer1 and timer3.
>> 3. pxa1928 has timer 2.
>> 
>> The driver supports DT and non-DT initialization.
>> The driver supports UP/SMP SOCes and 64 bit core.
>> 
>> Signed-off-by: Chao Xie 
>> ---
>>  .../devicetree/bindings/arm/mrvl/timer.txt |  61 +-
>>  drivers/clocksource/Makefile   |   1 +
>>  drivers/clocksource/timer-mmp.c| 837 
>> +
>>  include/linux/mmp_timer.h  |  40 +
>>  4 files changed, 933 insertions(+), 6 deletions(-)  create mode 
>> 100644 drivers/clocksource/timer-mmp.c  create mode 100644 
>> include/linux/mmp_timer.h
>> 
>> diff --git a/Documentation/devicetree/bindings/arm/mrvl/timer.txt 
>> b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
>> index 9a6e251..b49cb3e 100644
>> --- a/Documentation/devicetree/bindings/arm/mrvl/timer.txt
>> +++ b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
>> @@ -1,13 +1,62 @@
>>  * Marvell MMP Timer controller
>> 
>> +Each timer have multiple counters, so the timer DT need include 
>> +counter's description.
>> +
>> +1. Timer
>> +
>>  Required properties:
>> -- compatible : Should be "mrvl,mmp-timer".
>> +- compatible : Should be "marvell,mmp-timer".
>>  - reg : Address and length of the register set of timer controller.
>> -- interrupts : Should be the interrupt number.
>> +- clocks : The first clock is the fequency of the apb bus that the 
>> +timer
>> +  attached to. The second clock is the fast clock frequency of the timer.
>> +  This frequency and fast clock are used to calculated delay
>> +  loops for clock operations.
>
>It might be a good idea to use clock-names for "apb" and "fast" and use them 
>in the driver.

>


Yes. I will fix it.

>> +
>> +Optional properties:
>> +- marvell,timer-has-crsr : This timer has CRSR register.
>> +- marvell,timer-has-shadow : This timer has shadow register.
>> +
>> +2. Counter
>
>The coutner nodes appear to be sub-nodes of the timer. That should be stated 
>explicitly.

>


I will fix it.


>> +>> +Required properties:
>> +- compatible : It can be
>> +  "marvell,timer-counter-clkevt" : The counter is used for clock event
>> +   device.
>> +  "marvell,timer-counter-clksrc" : The counter is used for clock source.
>> +  "marvell,timer-counter-delay" : The counter is used for delay timer.
>
>These are all Linux-internal details. I don't see why we should need separate 
>strings; Linux should be able to allocate these as appropriate (and a single 
>timer should be able to be both a clocksource and a delay timer).
>
>Is there any reason you envisage for having separate strings here? It douesn't 
>make sense to me to do so.
>
>> +- marvell,timer-counter-id : The counter index in this timer.
>
>It sounds like you could use reg for this, unless you have other sub-nodes 
>you'll need to instantiate?
>
>> 
>> -Example:
>> -   timer0: timer@d4014000 {
>> -   compatible = "mrvl,mmp-timer";
>> -   reg = <0xd4014000 0x100>;
>> +Optional properties:
>> +- marvell,fast-clock : whether the counter use the fast-clock for counting.
>
>It looks below like this is a policy de

[PATCH 1/4] clocksource: mmp: add mmp timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie 

MMP timer is attached to APB bus, It has the following
limitation.
1. When get count of timer counter, it need some delay
   to get a stable count.
2. When set match register, it need disable the counter
   first, and enable it after set the match register.
   The disabling need wait for 2 clock cycle to take
   effect.

To improve above #1, shadow register for count is added.
To improve above #2, CRSR register is added for quick updating.

So there are three types of timer.
timer1: old timer.
timer2: old timer with shadow register.
timer3: old timer with shadow and CRSR register.

This timer driver will be used for many SOCes.
1. pxa168, pxa910, pxa988 pxa1088 have only timer1.
2. pxa1L88, pxa1U88 have timer1 and timer3.
3. pxa1928 has timer 2.

The driver supports DT and non-DT initialization.
The driver supports UP/SMP SOCes and 64 bit core.

Signed-off-by: Chao Xie 
---
 .../devicetree/bindings/arm/mrvl/timer.txt |  61 +-
 drivers/clocksource/Makefile   |   1 +
 drivers/clocksource/timer-mmp.c| 837 +
 include/linux/mmp_timer.h  |  40 +
 4 files changed, 933 insertions(+), 6 deletions(-)
 create mode 100644 drivers/clocksource/timer-mmp.c
 create mode 100644 include/linux/mmp_timer.h

diff --git a/Documentation/devicetree/bindings/arm/mrvl/timer.txt 
b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
index 9a6e251..b49cb3e 100644
--- a/Documentation/devicetree/bindings/arm/mrvl/timer.txt
+++ b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
@@ -1,13 +1,62 @@
 * Marvell MMP Timer controller
 
+Each timer have multiple counters, so the timer DT need include counter's
+description.
+
+1. Timer
+
 Required properties:
-- compatible : Should be "mrvl,mmp-timer".
+- compatible : Should be "marvell,mmp-timer".
 - reg : Address and length of the register set of timer controller.
-- interrupts : Should be the interrupt number.
+- clocks : The first clock is the fequency of the apb bus that the timer
+  attached to. The second clock is the fast clock frequency of the timer.
+  This frequency and fast clock are used to calculated delay
+  loops for clock operations.
+
+Optional properties:
+- marvell,timer-has-crsr : This timer has CRSR register.
+- marvell,timer-has-shadow : This timer has shadow register.
+
+2. Counter
+
+Required properties:
+- compatible : It can be
+  "marvell,timer-counter-clkevt" : The counter is used for clock event
+   device.
+  "marvell,timer-counter-clksrc" : The counter is used for clock source.
+  "marvell,timer-counter-delay" : The counter is used for delay timer.
+- marvell,timer-counter-id : The counter index in this timer.
 
-Example:
-   timer0: timer@d4014000 {
-   compatible = "mrvl,mmp-timer";
-   reg = <0xd4014000 0x100>;
+Optional properties:
+- marvell,fast-clock : whether the counter use the fast-clock for counting.
+- interrupts : The interrupt for clock event device.
+  Only valid for "marvell,timer-counter-clkevt".
+- marvell,timer-counter-cpu : which CPU the counter is bound. Only valid for
+  "marvell,timer-counter-clkevt".
+- marvell,timer-counter-broadcast : When this counter acts as clock event
+  device. It is broadcast clock event device.
+  Only valid for "marvell,timer-counter-clkevt".
+- marvell,timer-counter-nodynirq : When this counter acts as broadcast clock
+  event device, it cannot switch the IRQ of broadcast clock event to any CPU.
+  Only valid for "marvell,timer-counter-clkevt".
+
+3. Examples
+
+timer0: timer@d4014000 {
+   compatible = "marvell,mmp-timer";
+   reg = <0xd4014000 0xc8>;
+   clocks = <_clocks MMP2_PLL1_24>, <_closk MMP2_CLK_TIMER>;
+   status = "okay";
+
+   counter0 {
+   compatible = "marvell,timer-counter-clkevt";
interrupts = <13>;
+   marvell,timer-counter-id = <0>;
+   marvell,timer-counter-cpu = <0>;
+   };
+
+   counter1 {
+   compatible = "marvell,timer-counter-clksrc";
+   marvell,timer-counter-id = <1>;
};
+};
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b2..6a66d4d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_ORION_TIMER) += time-orion.o
 obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
 obj-$(CONFIG_ARCH_CLPS711X)+= clps711x-timer.o
 obj-$(CONFIG_ARCH_MARCO)   += timer-marco.o
+obj-$(CONFIG_ARCH_MMP) += timer-mmp.o
 obj-$(CONFIG_ARCH_MOXART)  += moxart_timer.o
 obj-$(CONFIG_ARCH_MXS) += mxs_timer.o
 obj-$(CONFIG_ARCH_PXA) += pxa_timer.o
diff --git a/drivers/clocksource/timer-mmp.

[PATCH 4/4] arm: mmp: remove the old timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie 

The new timer driver has been created under
drivers/clocksource/.

After change all SOCes to use the new driver,
remove the old one.

Signed-off-by: Chao Xie 
---
 arch/arm/mach-mmp/Makefile |   2 +-
 arch/arm/mach-mmp/time.c   | 247 -
 2 files changed, 1 insertion(+), 248 deletions(-)
 delete mode 100644 arch/arm/mach-mmp/time.c

diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 98f0f63..18ba814 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for Marvell's PXA168 processors line
 #
 
-obj-y  += common.o devices.o time.o
+obj-y  += common.o devices.o
 
 # SoC support
 obj-$(CONFIG_CPU_PXA168)   += pxa168.o
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
deleted file mode 100644
index 2756351..000
--- a/arch/arm/mach-mmp/time.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/time.c
- *
- *   Support for clocksource and clockevents
- *
- * Copyright (C) 2008 Marvell International Ltd.
- * All rights reserved.
- *
- *   2008-04-11: Jason Chagas 
- *   2008-10-08: Bin Yang 
- *
- * The timers module actually includes three timers, each timer with up to
- * three match comparators. Timer #0 is used here in free-running mode as
- * the clock source, and match comparator #1 used as clock event device.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "clock.h"
-
-#ifdef CONFIG_CPU_MMP2
-#define MMP_CLOCK_FREQ 650
-#else
-#define MMP_CLOCK_FREQ 325
-#endif
-
-#define TIMERS_VIRT_BASE   TIMERS1_VIRT_BASE
-
-#define MAX_DELTA  (0xfffe)
-#define MIN_DELTA  (16)
-
-static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
-
-/*
- * FIXME: the timer needs some delay to stablize the counter capture
- */
-static inline uint32_t timer_read(void)
-{
-   int delay = 100;
-
-   __raw_writel(1, mmp_timer_base + TMR_CVWR(1));
-
-   while (delay--)
-   cpu_relax();
-
-   return __raw_readl(mmp_timer_base + TMR_CVWR(1));
-}
-
-static u64 notrace mmp_read_sched_clock(void)
-{
-   return timer_read();
-}
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-   struct clock_event_device *c = dev_id;
-
-   /*
-* Clear pending interrupt status.
-*/
-   __raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
-
-   /*
-* Disable timer 0.
-*/
-   __raw_writel(0x02, mmp_timer_base + TMR_CER);
-
-   c->event_handler(c);
-
-   return IRQ_HANDLED;
-}
-
-static int timer_set_next_event(unsigned long delta,
-   struct clock_event_device *dev)
-{
-   unsigned long flags;
-
-   local_irq_save(flags);
-
-   /*
-* Disable timer 0.
-*/
-   __raw_writel(0x02, mmp_timer_base + TMR_CER);
-
-   /*
-* Clear and enable timer match 0 interrupt.
-*/
-   __raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
-   __raw_writel(0x01, mmp_timer_base + TMR_IER(0));
-
-   /*
-* Setup new clockevent timer value.
-*/
-   __raw_writel(delta - 1, mmp_timer_base + TMR_TN_MM(0, 0));
-
-   /*
-* Enable timer 0.
-*/
-   __raw_writel(0x03, mmp_timer_base + TMR_CER);
-
-   local_irq_restore(flags);
-
-   return 0;
-}
-
-static void timer_set_mode(enum clock_event_mode mode,
-  struct clock_event_device *dev)
-{
-   unsigned long flags;
-
-   local_irq_save(flags);
-   switch (mode) {
-   case CLOCK_EVT_MODE_ONESHOT:
-   case CLOCK_EVT_MODE_UNUSED:
-   case CLOCK_EVT_MODE_SHUTDOWN:
-   /* disable the matching interrupt */
-   __raw_writel(0x00, mmp_timer_base + TMR_IER(0));
-   break;
-   case CLOCK_EVT_MODE_RESUME:
-   case CLOCK_EVT_MODE_PERIODIC:
-   break;
-   }
-   local_irq_restore(flags);
-}
-
-static struct clock_event_device ckevt = {
-   .name   = "clockevent",
-   .features   = CLOCK_EVT_FEAT_ONESHOT,
-   .rating = 200,
-   .set_next_event = timer_set_next_event,
-   .set_mode   = timer_set_mode,
-};
-
-static cycle_t clksrc_read(struct clocksource *cs)
-{
-   return timer_read();
-}
-
-static struct clocksource cksrc = {
-   .name   = "clocksource",
-   .rating = 200,
-   .read   = clksrc_read,
-   .mask   = CLOCKSOURCE_MASK(32),
-   .flags  = CLOCK_SOURCE_IS_CONT

[PATCH 0/4] drivers: clocksource: add mmp timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie 

These patch will create a new timer driver in drivers/clocksource/
The timer driver will support all SOCes in mach-mmp

There are two patches #2 and #3 changing the arch/mach-mmp to make
DT and no-DT supported SOCes to make use of new timer driver

The final patch will remove the old timer driver.

The patches are tested at pxa910 and mmp2(DT and no-DT support).
Because pxa168 is too old, and it is hard to find the board.
So only pass the compiling.

Chao Xie (4):
  clocksource: mmp: add mmp timer driver
  arm: mmp: make SOCes without DT use new timer driver
  arm: mmp: make SOCes with DT use new timer driver
  arm: mmp: remove the old timer driver

 .../devicetree/bindings/arm/mrvl/timer.txt |  61 +-
 arch/arm/boot/dts/mmp2.dtsi|  19 +-
 arch/arm/boot/dts/pxa168.dtsi  |  20 +-
 arch/arm/boot/dts/pxa910.dtsi  |  26 +-
 arch/arm/mach-mmp/Kconfig  |   2 +
 arch/arm/mach-mmp/Makefile |   2 +-
 arch/arm/mach-mmp/common.h |   2 -
 arch/arm/mach-mmp/mmp-dt.c |   4 +-
 arch/arm/mach-mmp/mmp2-dt.c|   4 +-
 arch/arm/mach-mmp/mmp2.c   |  23 +-
 arch/arm/mach-mmp/pxa168.c |  23 +-
 arch/arm/mach-mmp/pxa910.c |  24 +-
 arch/arm/mach-mmp/time.c   | 247 --
 drivers/clocksource/Makefile   |   1 +
 drivers/clocksource/timer-mmp.c| 837 +
 include/linux/mmp_timer.h  |  40 +
 16 files changed, 1058 insertions(+), 277 deletions(-)
 delete mode 100644 arch/arm/mach-mmp/time.c
 create mode 100644 drivers/clocksource/timer-mmp.c
 create mode 100644 include/linux/mmp_timer.h

-- 
1.8.3.2

--
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 2/4] arm: mmp: make SOCes without DT use new timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie 

For no DT support, directly call new timer's APIs to initialize
timer.
It need to initialize the timer first, then initialize the clock
event device or clock source which are based on counter.

Signed-off-by: Chao Xie 
---
 arch/arm/mach-mmp/common.h |  2 --
 arch/arm/mach-mmp/mmp2.c   | 23 ++-
 arch/arm/mach-mmp/pxa168.c | 23 ++-
 arch/arm/mach-mmp/pxa910.c | 24 +++-
 4 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index cf445ba..015b209 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -1,8 +1,6 @@
 #include 
 #define ARRAY_AND_SIZE(x)  (x), ARRAY_SIZE(x)
 
-extern void timer_init(int irq);
-
 extern void __init mmp_map_io(void);
 extern void mmp_restart(enum reboot_mode, const char *);
 extern void __init pxa168_clk_init(void);
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index a70b553..12ba28a 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -16,12 +16,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -133,7 +135,26 @@ void __init mmp2_timer_init(void)
clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
__raw_writel(clk_rst, APBC_TIMERS);
 
-   timer_init(IRQ_MMP2_TIMER1);
+   /*
+* Make use of timer 1 which id is 0.
+* It has no shadow and crsr regsiters.
+* The fast lock is 6.5M.
+* apb bus is 26M.
+*/
+   mmp_timer_init(0, TIMERS1_VIRT_BASE, 0, 650, 2600);
+
+   /*
+* Enable counter 1 to be clock source.
+* The frequency is 32K.
+*/
+   mmp_counter_clocksource_init(0, 1, 32768);
+
+   /*
+* Enable counter 0 to be clock event device.
+* The frequency is 32K.
+* Only one cpu and there is no broadcast timer.
+*/
+   mmp_counter_clockevent_init(0, 0, IRQ_MMP2_TIMER1, 32768, 0, 0);
 }
 
 /* on-chip devices */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 144e997..bb65d8f 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -22,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -78,7 +80,26 @@ void __init pxa168_timer_init(void)
/* 3.25MHz, bus/functional clock enabled, release reset */
__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
 
-   timer_init(IRQ_PXA168_TIMER1);
+   /*
+* Make use of timer 1 which id is 0.
+* It has no shadow and crsr regsiters.
+* The fast lock is 3.25M.
+* apb bus is 26M.
+*/
+   mmp_timer_init(0, TIMERS1_VIRT_BASE, 0, 325, 2600);
+
+   /*
+* Enable counter 1 to be clock source.
+* The frequency is 32K.
+*/
+   mmp_counter_clocksource_init(0, 1, 32768);
+
+   /*
+* Enable counter 0 to be clock event device.
+* The frequency is 32K.
+* Only one cpu and there is no broadcast timer.
+*/
+   mmp_counter_clockevent_init(0, 0, IRQ_PXA168_TIMER1, 32768, 0, 0);
 }
 
 void pxa168_clear_keypad_wakeup(void)
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index eb57ee1..e8ae5b1 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -15,11 +15,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -114,7 +116,27 @@ void __init pxa910_timer_init(void)
__raw_writel(APBC_APBCLK | APBC_RST, APBC_TIMERS);
__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
 
-   timer_init(IRQ_PXA910_AP1_TIMER1);
+   /*
+* Make use of timer 1 which id is 0.
+* It has no shadow and crsr regsiters.
+* The fast lock is 3.25M.
+* apb bus is 26M.
+*/
+   mmp_timer_init(0, TIMERS1_VIRT_BASE, 0, 325, 2600);
+
+   /*
+* Enable counter 1 to be clock source.
+* The frequency is 32K.
+*/
+   mmp_counter_clocksource_init(0, 1, 32768);
+
+   /*
+* Enable counter 0 to be clock event device.
+* The frequency is 32K.
+* Only one cpu and there is no broadcast timer.
+*/
+   mmp_counter_clockevent_init(0, 0, IRQ_PXA910_AP1_TIMER1,
+   32768, 0, 0);
 }
 
 /* on-chip devices */
-- 
1.8.3.2

--
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 3/4] arm: mmp: make SOCes with DT use new timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie 

Change the dtsi and DT support for mmp SOCes to make them
use the new timer driver.

Signed-off-by: Chao Xie 
---
 arch/arm/boot/dts/mmp2.dtsi   | 19 ---
 arch/arm/boot/dts/pxa168.dtsi | 20 +---
 arch/arm/boot/dts/pxa910.dtsi | 26 --
 arch/arm/mach-mmp/Kconfig |  2 ++
 arch/arm/mach-mmp/mmp-dt.c|  4 +++-
 arch/arm/mach-mmp/mmp2-dt.c   |  4 +++-
 6 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 766bbb8..e63e3a3 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -127,9 +127,22 @@
ranges;
 
timer0: timer@d4014000 {
-   compatible = "mrvl,mmp-timer";
-   reg = <0xd4014000 0x100>;
-   interrupts = <13>;
+   compatible = "marvell,mmp-timer";
+   reg = <0xd4014000 0xc8>;
+   clocks = <_clocks MMP2_CLK_VCTCXO>, 
<_clocks MMP2_CLK_TIMER>;
+   status = "okay";
+
+   counter0 {
+   compatible = 
"marvell,timer-counter-clkevt";
+   interrupts = <13>;
+   marvell,timer-counter-id = <0>;
+   marvell,timer-counter-cpu = <0>;
+};
+
+counter1 {
+   compatible = 
"marvell,timer-counter-clksrc";
+   marvell,timer-counter-id = <1>;
+};
};
 
uart1: uart@d403 {
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index b899e25..5a2f385 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -51,9 +51,23 @@
ranges;
 
timer0: timer@d4014000 {
-   compatible = "mrvl,mmp-timer";
-   reg = <0xd4014000 0x100>;
-   interrupts = <13>;
+   compatible = "marvell,mmp-timer";
+   reg = <0xd4014000 0xc8>;
+   clocks = <_clocks PXA168_CLK_PLL1_24>, 
<_clocks PXA168_CLK_TIMER>;
+   status = "okay";
+
+   counter0 {
+   compatible = 
"marvell,timer-counter-clkevt";
+   interrupts = <13>;
+   marvell,timer-counter-id = <0>;
+   marvell,timer-counter-cpu = <0>;
+};
+
+counter1 {
+   compatible = 
"marvell,timer-counter-clksrc";
+   marvell,timer-counter-id = <1>;
+};
+
};
 
uart1: uart@d4017000 {
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 0868f67..beb25fc 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -56,16 +56,22 @@
ranges;
 
timer0: timer@d4014000 {
-   compatible = "mrvl,mmp-timer";
-   reg = <0xd4014000 0x100>;
-   interrupts = <13>;
-   };
-
-   timer1: timer@d4016000 {
-   compatible = "mrvl,mmp-timer";
-   reg = <0xd4016000 0x100>;
-   interrupts = <29>;
-   status = "disabled";
+   compatible = "marvell,mmp-timer";
+   reg = <0xd4014000 0xc8>;
+   clocks = <_clocks PXA910_CLK_PLL1_24>, 
<_clocks PXA910_CLK_TIMER0>;
+   status = "okay";
+
+   counter0 {
+   compatible = 
"marvell,timer-counter-clkevt";
+   interrupts = <13>;
+   marvell,timer-counter-id = <0>;
+   marvell,timer-counter-cpu = <0>;
+   

Re: [PATCH 1/4] clocksource: mmp: add mmp timer driver

2015-02-02 Thread Chao Xie



From: Mark Rutland [mailto:mark.rutl...@arm.com] 
Sent: 2015年2月2日 18:35
To: Chao Xie
Cc: daniel.lezc...@linaro.org; t...@linutronix.de; haojian.zhu...@linaro.org; 
linux-kernel@vger.kernel.org; devicet...@vger.kernel.org
Subject: Re: [PATCH 1/4] clocksource: mmp: add mmp timer driver

On Mon, Feb 02, 2015 at 08:31:36AM +, Chao Xie wrote:
 From: Chao Xie chao@marvell.com
 
 MMP timer is attached to APB bus, It has the following limitation.
 1. When get count of timer counter, it need some delay
to get a stable count.
 2. When set match register, it need disable the counter
first, and enable it after set the match register.
The disabling need wait for 2 clock cycle to take
effect.
 
 To improve above #1, shadow register for count is added.
 To improve above #2, CRSR register is added for quick updating.
 
 So there are three types of timer.
 timer1: old timer.
 timer2: old timer with shadow register.
 timer3: old timer with shadow and CRSR register.
 
 This timer driver will be used for many SOCes.
 1. pxa168, pxa910, pxa988 pxa1088 have only timer1.
 2. pxa1L88, pxa1U88 have timer1 and timer3.
 3. pxa1928 has timer 2.
 
 The driver supports DT and non-DT initialization.
 The driver supports UP/SMP SOCes and 64 bit core.
 
 Signed-off-by: Chao Xie chao@marvell.com
 ---
  .../devicetree/bindings/arm/mrvl/timer.txt |  61 +-
  drivers/clocksource/Makefile   |   1 +
  drivers/clocksource/timer-mmp.c| 837 
 +
  include/linux/mmp_timer.h  |  40 +
  4 files changed, 933 insertions(+), 6 deletions(-)  create mode 
 100644 drivers/clocksource/timer-mmp.c  create mode 100644 
 include/linux/mmp_timer.h
 
 diff --git a/Documentation/devicetree/bindings/arm/mrvl/timer.txt 
 b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
 index 9a6e251..b49cb3e 100644
 --- a/Documentation/devicetree/bindings/arm/mrvl/timer.txt
 +++ b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
 @@ -1,13 +1,62 @@
  * Marvell MMP Timer controller
 
 +Each timer have multiple counters, so the timer DT need include 
 +counter's description.
 +
 +1. Timer
 +
  Required properties:
 -- compatible : Should be mrvl,mmp-timer.
 +- compatible : Should be marvell,mmp-timer.
  - reg : Address and length of the register set of timer controller.
 -- interrupts : Should be the interrupt number.
 +- clocks : The first clock is the fequency of the apb bus that the 
 +timer
 +  attached to. The second clock is the fast clock frequency of the timer.
 +  This frequency and fast clock are used to calculated delay
 +  loops for clock operations.

It might be a good idea to use clock-names for apb and fast and use them 
in the driver.




Yes. I will fix it.

 +
 +Optional properties:
 +- marvell,timer-has-crsr : This timer has CRSR register.
 +- marvell,timer-has-shadow : This timer has shadow register.
 +
 +2. Counter

The coutner nodes appear to be sub-nodes of the timer. That should be stated 
explicitly.




I will fix it.


 + +Required properties:
 +- compatible : It can be
 +  marvell,timer-counter-clkevt : The counter is used for clock event
 +   device.
 +  marvell,timer-counter-clksrc : The counter is used for clock source.
 +  marvell,timer-counter-delay : The counter is used for delay timer.

These are all Linux-internal details. I don't see why we should need separate 
strings; Linux should be able to allocate these as appropriate (and a single 
timer should be able to be both a clocksource and a delay timer).

Is there any reason you envisage for having separate strings here? It douesn't 
make sense to me to do so.

 +- marvell,timer-counter-id : The counter index in this timer.

It sounds like you could use reg for this, unless you have other sub-nodes 
you'll need to instantiate?

 
 -Example:
 -   timer0: timer@d4014000 {
 -   compatible = mrvl,mmp-timer;
 -   reg = 0xd4014000 0x100;
 +Optional properties:
 +- marvell,fast-clock : whether the counter use the fast-clock for counting.

It looks below like this is a policy decision, rather than a description of 
the HW. When would you select the fast clock and when would you not?
Why can't the driver figure this out?




The name is a little confused. There are two types of fast clock inputs in all 
the SOCes. From vctcxo or PLL1.
In some low power mode, PLL1 will be shutdown, and timer can not use this clock 
because it need wake up the cores when time out.
Timer driver can not get the information that whether this fast clock is coming 
from a clock source that will be shutdown in the low
power mode or not.
So i need tell it in the device tree that the fast clock is still active in the 
low power mode.


 +- interrupts : The interrupt for clock event device. +  Only valid for 
 marvell,timer-counter-clkevt.
 +- marvell,timer-counter-cpu : which CPU the counter is bound. Only 
 +valid

[PATCH 4/4] arm: mmp: remove the old timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie chao@marvell.com

The new timer driver has been created under
drivers/clocksource/.

After change all SOCes to use the new driver,
remove the old one.

Signed-off-by: Chao Xie chao@marvell.com
---
 arch/arm/mach-mmp/Makefile |   2 +-
 arch/arm/mach-mmp/time.c   | 247 -
 2 files changed, 1 insertion(+), 248 deletions(-)
 delete mode 100644 arch/arm/mach-mmp/time.c

diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 98f0f63..18ba814 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for Marvell's PXA168 processors line
 #
 
-obj-y  += common.o devices.o time.o
+obj-y  += common.o devices.o
 
 # SoC support
 obj-$(CONFIG_CPU_PXA168)   += pxa168.o
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
deleted file mode 100644
index 2756351..000
--- a/arch/arm/mach-mmp/time.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/time.c
- *
- *   Support for clocksource and clockevents
- *
- * Copyright (C) 2008 Marvell International Ltd.
- * All rights reserved.
- *
- *   2008-04-11: Jason Chagas jason.cha...@marvell.com
- *   2008-10-08: Bin Yang bin.y...@marvell.com
- *
- * The timers module actually includes three timers, each timer with up to
- * three match comparators. Timer #0 is used here in free-running mode as
- * the clock source, and match comparator #1 used as clock event device.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include linux/init.h
-#include linux/kernel.h
-#include linux/interrupt.h
-#include linux/clockchips.h
-
-#include linux/io.h
-#include linux/irq.h
-#include linux/of.h
-#include linux/of_address.h
-#include linux/of_irq.h
-#include linux/sched_clock.h
-
-#include mach/addr-map.h
-#include mach/regs-timers.h
-#include mach/regs-apbc.h
-#include mach/irqs.h
-#include mach/cputype.h
-#include asm/mach/time.h
-
-#include clock.h
-
-#ifdef CONFIG_CPU_MMP2
-#define MMP_CLOCK_FREQ 650
-#else
-#define MMP_CLOCK_FREQ 325
-#endif
-
-#define TIMERS_VIRT_BASE   TIMERS1_VIRT_BASE
-
-#define MAX_DELTA  (0xfffe)
-#define MIN_DELTA  (16)
-
-static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
-
-/*
- * FIXME: the timer needs some delay to stablize the counter capture
- */
-static inline uint32_t timer_read(void)
-{
-   int delay = 100;
-
-   __raw_writel(1, mmp_timer_base + TMR_CVWR(1));
-
-   while (delay--)
-   cpu_relax();
-
-   return __raw_readl(mmp_timer_base + TMR_CVWR(1));
-}
-
-static u64 notrace mmp_read_sched_clock(void)
-{
-   return timer_read();
-}
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-   struct clock_event_device *c = dev_id;
-
-   /*
-* Clear pending interrupt status.
-*/
-   __raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
-
-   /*
-* Disable timer 0.
-*/
-   __raw_writel(0x02, mmp_timer_base + TMR_CER);
-
-   c-event_handler(c);
-
-   return IRQ_HANDLED;
-}
-
-static int timer_set_next_event(unsigned long delta,
-   struct clock_event_device *dev)
-{
-   unsigned long flags;
-
-   local_irq_save(flags);
-
-   /*
-* Disable timer 0.
-*/
-   __raw_writel(0x02, mmp_timer_base + TMR_CER);
-
-   /*
-* Clear and enable timer match 0 interrupt.
-*/
-   __raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
-   __raw_writel(0x01, mmp_timer_base + TMR_IER(0));
-
-   /*
-* Setup new clockevent timer value.
-*/
-   __raw_writel(delta - 1, mmp_timer_base + TMR_TN_MM(0, 0));
-
-   /*
-* Enable timer 0.
-*/
-   __raw_writel(0x03, mmp_timer_base + TMR_CER);
-
-   local_irq_restore(flags);
-
-   return 0;
-}
-
-static void timer_set_mode(enum clock_event_mode mode,
-  struct clock_event_device *dev)
-{
-   unsigned long flags;
-
-   local_irq_save(flags);
-   switch (mode) {
-   case CLOCK_EVT_MODE_ONESHOT:
-   case CLOCK_EVT_MODE_UNUSED:
-   case CLOCK_EVT_MODE_SHUTDOWN:
-   /* disable the matching interrupt */
-   __raw_writel(0x00, mmp_timer_base + TMR_IER(0));
-   break;
-   case CLOCK_EVT_MODE_RESUME:
-   case CLOCK_EVT_MODE_PERIODIC:
-   break;
-   }
-   local_irq_restore(flags);
-}
-
-static struct clock_event_device ckevt = {
-   .name   = clockevent,
-   .features   = CLOCK_EVT_FEAT_ONESHOT,
-   .rating = 200,
-   .set_next_event = timer_set_next_event,
-   .set_mode   = timer_set_mode,
-};
-
-static cycle_t clksrc_read(struct clocksource *cs

[PATCH 1/4] clocksource: mmp: add mmp timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie chao@marvell.com

MMP timer is attached to APB bus, It has the following
limitation.
1. When get count of timer counter, it need some delay
   to get a stable count.
2. When set match register, it need disable the counter
   first, and enable it after set the match register.
   The disabling need wait for 2 clock cycle to take
   effect.

To improve above #1, shadow register for count is added.
To improve above #2, CRSR register is added for quick updating.

So there are three types of timer.
timer1: old timer.
timer2: old timer with shadow register.
timer3: old timer with shadow and CRSR register.

This timer driver will be used for many SOCes.
1. pxa168, pxa910, pxa988 pxa1088 have only timer1.
2. pxa1L88, pxa1U88 have timer1 and timer3.
3. pxa1928 has timer 2.

The driver supports DT and non-DT initialization.
The driver supports UP/SMP SOCes and 64 bit core.

Signed-off-by: Chao Xie chao@marvell.com
---
 .../devicetree/bindings/arm/mrvl/timer.txt |  61 +-
 drivers/clocksource/Makefile   |   1 +
 drivers/clocksource/timer-mmp.c| 837 +
 include/linux/mmp_timer.h  |  40 +
 4 files changed, 933 insertions(+), 6 deletions(-)
 create mode 100644 drivers/clocksource/timer-mmp.c
 create mode 100644 include/linux/mmp_timer.h

diff --git a/Documentation/devicetree/bindings/arm/mrvl/timer.txt 
b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
index 9a6e251..b49cb3e 100644
--- a/Documentation/devicetree/bindings/arm/mrvl/timer.txt
+++ b/Documentation/devicetree/bindings/arm/mrvl/timer.txt
@@ -1,13 +1,62 @@
 * Marvell MMP Timer controller
 
+Each timer have multiple counters, so the timer DT need include counter's
+description.
+
+1. Timer
+
 Required properties:
-- compatible : Should be mrvl,mmp-timer.
+- compatible : Should be marvell,mmp-timer.
 - reg : Address and length of the register set of timer controller.
-- interrupts : Should be the interrupt number.
+- clocks : The first clock is the fequency of the apb bus that the timer
+  attached to. The second clock is the fast clock frequency of the timer.
+  This frequency and fast clock are used to calculated delay
+  loops for clock operations.
+
+Optional properties:
+- marvell,timer-has-crsr : This timer has CRSR register.
+- marvell,timer-has-shadow : This timer has shadow register.
+
+2. Counter
+
+Required properties:
+- compatible : It can be
+  marvell,timer-counter-clkevt : The counter is used for clock event
+   device.
+  marvell,timer-counter-clksrc : The counter is used for clock source.
+  marvell,timer-counter-delay : The counter is used for delay timer.
+- marvell,timer-counter-id : The counter index in this timer.
 
-Example:
-   timer0: timer@d4014000 {
-   compatible = mrvl,mmp-timer;
-   reg = 0xd4014000 0x100;
+Optional properties:
+- marvell,fast-clock : whether the counter use the fast-clock for counting.
+- interrupts : The interrupt for clock event device.
+  Only valid for marvell,timer-counter-clkevt.
+- marvell,timer-counter-cpu : which CPU the counter is bound. Only valid for
+  marvell,timer-counter-clkevt.
+- marvell,timer-counter-broadcast : When this counter acts as clock event
+  device. It is broadcast clock event device.
+  Only valid for marvell,timer-counter-clkevt.
+- marvell,timer-counter-nodynirq : When this counter acts as broadcast clock
+  event device, it cannot switch the IRQ of broadcast clock event to any CPU.
+  Only valid for marvell,timer-counter-clkevt.
+
+3. Examples
+
+timer0: timer@d4014000 {
+   compatible = marvell,mmp-timer;
+   reg = 0xd4014000 0xc8;
+   clocks = soc_clocks MMP2_PLL1_24, soc_closk MMP2_CLK_TIMER;
+   status = okay;
+
+   counter0 {
+   compatible = marvell,timer-counter-clkevt;
interrupts = 13;
+   marvell,timer-counter-id = 0;
+   marvell,timer-counter-cpu = 0;
+   };
+
+   counter1 {
+   compatible = marvell,timer-counter-clksrc;
+   marvell,timer-counter-id = 1;
};
+};
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b2..6a66d4d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_ORION_TIMER) += time-orion.o
 obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
 obj-$(CONFIG_ARCH_CLPS711X)+= clps711x-timer.o
 obj-$(CONFIG_ARCH_MARCO)   += timer-marco.o
+obj-$(CONFIG_ARCH_MMP) += timer-mmp.o
 obj-$(CONFIG_ARCH_MOXART)  += moxart_timer.o
 obj-$(CONFIG_ARCH_MXS) += mxs_timer.o
 obj-$(CONFIG_ARCH_PXA) += pxa_timer.o
diff --git a/drivers/clocksource/timer-mmp.c b/drivers/clocksource/timer-mmp.c
new file mode 100644
index 000..b6a9ce1
--- /dev/null
+++ b/drivers/clocksource/timer-mmp.c
@@ -0,0 +1,837 @@
+/*
+ * driver/clocksource/timer-mmp.c

[PATCH 0/4] drivers: clocksource: add mmp timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie chao@marvell.com

These patch will create a new timer driver in drivers/clocksource/
The timer driver will support all SOCes in mach-mmp

There are two patches #2 and #3 changing the arch/mach-mmp to make
DT and no-DT supported SOCes to make use of new timer driver

The final patch will remove the old timer driver.

The patches are tested at pxa910 and mmp2(DT and no-DT support).
Because pxa168 is too old, and it is hard to find the board.
So only pass the compiling.

Chao Xie (4):
  clocksource: mmp: add mmp timer driver
  arm: mmp: make SOCes without DT use new timer driver
  arm: mmp: make SOCes with DT use new timer driver
  arm: mmp: remove the old timer driver

 .../devicetree/bindings/arm/mrvl/timer.txt |  61 +-
 arch/arm/boot/dts/mmp2.dtsi|  19 +-
 arch/arm/boot/dts/pxa168.dtsi  |  20 +-
 arch/arm/boot/dts/pxa910.dtsi  |  26 +-
 arch/arm/mach-mmp/Kconfig  |   2 +
 arch/arm/mach-mmp/Makefile |   2 +-
 arch/arm/mach-mmp/common.h |   2 -
 arch/arm/mach-mmp/mmp-dt.c |   4 +-
 arch/arm/mach-mmp/mmp2-dt.c|   4 +-
 arch/arm/mach-mmp/mmp2.c   |  23 +-
 arch/arm/mach-mmp/pxa168.c |  23 +-
 arch/arm/mach-mmp/pxa910.c |  24 +-
 arch/arm/mach-mmp/time.c   | 247 --
 drivers/clocksource/Makefile   |   1 +
 drivers/clocksource/timer-mmp.c| 837 +
 include/linux/mmp_timer.h  |  40 +
 16 files changed, 1058 insertions(+), 277 deletions(-)
 delete mode 100644 arch/arm/mach-mmp/time.c
 create mode 100644 drivers/clocksource/timer-mmp.c
 create mode 100644 include/linux/mmp_timer.h

-- 
1.8.3.2

--
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 3/4] arm: mmp: make SOCes with DT use new timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie chao@marvell.com

Change the dtsi and DT support for mmp SOCes to make them
use the new timer driver.

Signed-off-by: Chao Xie chao@marvell.com
---
 arch/arm/boot/dts/mmp2.dtsi   | 19 ---
 arch/arm/boot/dts/pxa168.dtsi | 20 +---
 arch/arm/boot/dts/pxa910.dtsi | 26 --
 arch/arm/mach-mmp/Kconfig |  2 ++
 arch/arm/mach-mmp/mmp-dt.c|  4 +++-
 arch/arm/mach-mmp/mmp2-dt.c   |  4 +++-
 6 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 766bbb8..e63e3a3 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -127,9 +127,22 @@
ranges;
 
timer0: timer@d4014000 {
-   compatible = mrvl,mmp-timer;
-   reg = 0xd4014000 0x100;
-   interrupts = 13;
+   compatible = marvell,mmp-timer;
+   reg = 0xd4014000 0xc8;
+   clocks = soc_clocks MMP2_CLK_VCTCXO, 
soc_clocks MMP2_CLK_TIMER;
+   status = okay;
+
+   counter0 {
+   compatible = 
marvell,timer-counter-clkevt;
+   interrupts = 13;
+   marvell,timer-counter-id = 0;
+   marvell,timer-counter-cpu = 0;
+};
+
+counter1 {
+   compatible = 
marvell,timer-counter-clksrc;
+   marvell,timer-counter-id = 1;
+};
};
 
uart1: uart@d403 {
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index b899e25..5a2f385 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -51,9 +51,23 @@
ranges;
 
timer0: timer@d4014000 {
-   compatible = mrvl,mmp-timer;
-   reg = 0xd4014000 0x100;
-   interrupts = 13;
+   compatible = marvell,mmp-timer;
+   reg = 0xd4014000 0xc8;
+   clocks = soc_clocks PXA168_CLK_PLL1_24, 
soc_clocks PXA168_CLK_TIMER;
+   status = okay;
+
+   counter0 {
+   compatible = 
marvell,timer-counter-clkevt;
+   interrupts = 13;
+   marvell,timer-counter-id = 0;
+   marvell,timer-counter-cpu = 0;
+};
+
+counter1 {
+   compatible = 
marvell,timer-counter-clksrc;
+   marvell,timer-counter-id = 1;
+};
+
};
 
uart1: uart@d4017000 {
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 0868f67..beb25fc 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -56,16 +56,22 @@
ranges;
 
timer0: timer@d4014000 {
-   compatible = mrvl,mmp-timer;
-   reg = 0xd4014000 0x100;
-   interrupts = 13;
-   };
-
-   timer1: timer@d4016000 {
-   compatible = mrvl,mmp-timer;
-   reg = 0xd4016000 0x100;
-   interrupts = 29;
-   status = disabled;
+   compatible = marvell,mmp-timer;
+   reg = 0xd4014000 0xc8;
+   clocks = soc_clocks PXA910_CLK_PLL1_24, 
soc_clocks PXA910_CLK_TIMER0;
+   status = okay;
+
+   counter0 {
+   compatible = 
marvell,timer-counter-clkevt;
+   interrupts = 13;
+   marvell,timer-counter-id = 0;
+   marvell,timer-counter-cpu = 0;
+};
+
+counter1 {
+   compatible = 
marvell,timer-counter-clksrc;
+   marvell,timer-counter-id = 1;
+};
};
 
uart1: uart@d4017000 {
diff --git a/arch/arm

[PATCH 2/4] arm: mmp: make SOCes without DT use new timer driver

2015-02-02 Thread Chao Xie
From: Chao Xie chao@marvell.com

For no DT support, directly call new timer's APIs to initialize
timer.
It need to initialize the timer first, then initialize the clock
event device or clock source which are based on counter.

Signed-off-by: Chao Xie chao@marvell.com
---
 arch/arm/mach-mmp/common.h |  2 --
 arch/arm/mach-mmp/mmp2.c   | 23 ++-
 arch/arm/mach-mmp/pxa168.c | 23 ++-
 arch/arm/mach-mmp/pxa910.c | 24 +++-
 4 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index cf445ba..015b209 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -1,8 +1,6 @@
 #include linux/reboot.h
 #define ARRAY_AND_SIZE(x)  (x), ARRAY_SIZE(x)
 
-extern void timer_init(int irq);
-
 extern void __init mmp_map_io(void);
 extern void mmp_restart(enum reboot_mode, const char *);
 extern void __init pxa168_clk_init(void);
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index a70b553..12ba28a 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -16,12 +16,14 @@
 #include linux/irq.h
 #include linux/irqchip/mmp.h
 #include linux/platform_device.h
+#include linux/mmp_timer.h
 
 #include asm/hardware/cache-tauros2.h
 
 #include asm/mach/time.h
 #include mach/addr-map.h
 #include mach/regs-apbc.h
+#include mach/regs-timers.h
 #include mach/cputype.h
 #include mach/irqs.h
 #include mach/dma.h
@@ -133,7 +135,26 @@ void __init mmp2_timer_init(void)
clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
__raw_writel(clk_rst, APBC_TIMERS);
 
-   timer_init(IRQ_MMP2_TIMER1);
+   /*
+* Make use of timer 1 which id is 0.
+* It has no shadow and crsr regsiters.
+* The fast lock is 6.5M.
+* apb bus is 26M.
+*/
+   mmp_timer_init(0, TIMERS1_VIRT_BASE, 0, 650, 2600);
+
+   /*
+* Enable counter 1 to be clock source.
+* The frequency is 32K.
+*/
+   mmp_counter_clocksource_init(0, 1, 32768);
+
+   /*
+* Enable counter 0 to be clock event device.
+* The frequency is 32K.
+* Only one cpu and there is no broadcast timer.
+*/
+   mmp_counter_clockevent_init(0, 0, IRQ_MMP2_TIMER1, 32768, 0, 0);
 }
 
 /* on-chip devices */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 144e997..bb65d8f 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -15,6 +15,7 @@
 #include linux/clk.h
 #include linux/platform_device.h
 #include linux/platform_data/mv_usb.h
+#include linux/mmp_timer.h
 
 #include asm/mach/time.h
 #include asm/system_misc.h
@@ -22,6 +23,7 @@
 #include mach/addr-map.h
 #include mach/regs-apbc.h
 #include mach/regs-apmu.h
+#include mach/regs-timers.h
 #include mach/irqs.h
 #include mach/dma.h
 #include mach/devices.h
@@ -78,7 +80,26 @@ void __init pxa168_timer_init(void)
/* 3.25MHz, bus/functional clock enabled, release reset */
__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
 
-   timer_init(IRQ_PXA168_TIMER1);
+   /*
+* Make use of timer 1 which id is 0.
+* It has no shadow and crsr regsiters.
+* The fast lock is 3.25M.
+* apb bus is 26M.
+*/
+   mmp_timer_init(0, TIMERS1_VIRT_BASE, 0, 325, 2600);
+
+   /*
+* Enable counter 1 to be clock source.
+* The frequency is 32K.
+*/
+   mmp_counter_clocksource_init(0, 1, 32768);
+
+   /*
+* Enable counter 0 to be clock event device.
+* The frequency is 32K.
+* Only one cpu and there is no broadcast timer.
+*/
+   mmp_counter_clockevent_init(0, 0, IRQ_PXA168_TIMER1, 32768, 0, 0);
 }
 
 void pxa168_clear_keypad_wakeup(void)
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index eb57ee1..e8ae5b1 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -15,11 +15,13 @@
 #include linux/irq.h
 #include linux/irqchip/mmp.h
 #include linux/platform_device.h
+#include linux/mmp_timer.h
 
 #include asm/hardware/cache-tauros2.h
 #include asm/mach/time.h
 #include mach/addr-map.h
 #include mach/regs-apbc.h
+#include mach/regs-timers.h
 #include mach/cputype.h
 #include mach/irqs.h
 #include mach/dma.h
@@ -114,7 +116,27 @@ void __init pxa910_timer_init(void)
__raw_writel(APBC_APBCLK | APBC_RST, APBC_TIMERS);
__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
 
-   timer_init(IRQ_PXA910_AP1_TIMER1);
+   /*
+* Make use of timer 1 which id is 0.
+* It has no shadow and crsr regsiters.
+* The fast lock is 3.25M.
+* apb bus is 26M.
+*/
+   mmp_timer_init(0, TIMERS1_VIRT_BASE, 0, 325, 2600);
+
+   /*
+* Enable counter 1 to be clock source.
+* The frequency is 32K.
+*/
+   mmp_counter_clocksource_init(0, 1, 32768);
+
+   /*
+* Enable counter 0

[PATCH] gpio: mmp: add GPIO driver for Marvell MMP series

2015-01-27 Thread Chao Xie
From: Chao Xie 

For some old PXA series, they used PXA GPIO driver.
The IP of GPIO changes since PXA988 which is Marvell MMP
series.
It will use new way to control the GPIO level, direction
and edge status.

Signed-off-by: Chao Xie 
---
 drivers/gpio/Kconfig|   7 +
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-mmp.c | 444 
 3 files changed, 452 insertions(+)
 create mode 100644 drivers/gpio/gpio-mmp.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 633ec21..c1e4e27 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -197,6 +197,13 @@ config GPIO_F7188X
  To compile this driver as a module, choose M here: the module will
  be called f7188x-gpio.
 
+config GPIO_MMP
+   bool "MMP GPIO support"
+   depends on ARCH_MMP
+   help
+ Say yes here to support the MMP GPIO device at 
PXA1088/PXA1908/PXA1928.
+ Comparing with PXA GPIO device, the IP of MMP GPIO changes a lot.
+
 config GPIO_MOXART
bool "MOXART GPIO support"
depends on ARCH_MOXART
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 81755f1..60a7cf5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
 obj-$(CONFIG_GPIO_MCP23S08)+= gpio-mcp23s08.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
+obj-$(CONFIG_GPIO_MMP) += gpio-mmp.o
 obj-$(CONFIG_GPIO_MOXART)  += gpio-moxart.o
 obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
diff --git a/drivers/gpio/gpio-mmp.c b/drivers/gpio/gpio-mmp.c
new file mode 100644
index 000..63e0766
--- /dev/null
+++ b/drivers/gpio/gpio-mmp.c
@@ -0,0 +1,444 @@
+/*
+ *  Copyright (C) 2014 Marvell International Ltd.
+ *
+ *  Generic MMP GPIO handling
+ *
+ * Chao Xie 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define GPLR   0x0
+#define GPDR   0xc
+#define GPSR   0x18
+#define GPCR   0x24
+#define GRER   0x30
+#define GFER   0x3c
+#define GEDR   0x48
+#define GSDR   0x54
+#define GCDR   0x60
+#define GSRER  0x6c
+#define GCRER  0x78
+#define GSFER  0x84
+#define GCFER  0x90
+#define GAPMASK0x9c
+#define GCPMASK0xa8
+
+/* Bank will have 2^n GPIOes, and for mmp-gpio n = 5 */
+#define BANK_GPIO_ORDER5
+#define BANK_GPIO_NUMBER   (1 << BANK_GPIO_ORDER)
+#define BANK_GPIO_MASK (BANK_GPIO_NUMBER - 1)
+
+#define mmp_gpio_to_bank_idx(gpio) ((gpio) >> BANK_GPIO_ORDER)
+#define mmp_gpio_to_bank_offset(gpio)  ((gpio) & BANK_GPIO_MASK)
+#define mmp_bank_to_gpio(idx, offset)  (((idx) << BANK_GPIO_ORDER) \
+   | ((offset) & BANK_GPIO_MASK))
+
+struct mmp_gpio_bank {
+   void __iomem *reg_bank;
+   u32 irq_mask;
+   u32 irq_rising_edge;
+   u32 irq_falling_edge;
+};
+
+struct mmp_gpio_chip {
+   struct gpio_chip chip;
+   void __iomem *reg_base;
+   int irq;
+   struct irq_domain *domain;
+   unsigned int ngpio;
+   unsigned int nbank;
+   struct mmp_gpio_bank *banks;
+};
+
+static int mmp_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+
+   return irq_create_mapping(mmp_chip->domain, offset);
+}
+
+static int mmp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   _chip->banks[mmp_gpio_to_bank_idx(offset)];
+   u32 bit = (1 << mmp_gpio_to_bank_offset(offset));
+
+   writel(bit, bank->reg_bank + GCDR);
+
+   return 0;
+}
+
+static int mmp_gpio_direction_output(struct gpio_chip *chip,
+unsigned offset, int value)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   _chip->banks[mmp_gpio_to_bank_idx(offset)];
+   u32 bit = (1 << mmp_gpio_to_bank_offset(offset));
+
+   /* Set value first. */
+   writel(bit, bank->reg_bank + (value ? GPSR : GPCR));
+
+   writel(bit, bank->reg_bank + GSDR);
+
+   return 0;
+}
+
+static int mmp_gpio_get(struct

[PATCH] gpio: mmp: add GPIO driver for Marvell MMP series

2015-01-27 Thread Chao Xie
From: Chao Xie chao@marvell.com

For some old PXA series, they used PXA GPIO driver.
The IP of GPIO changes since PXA988 which is Marvell MMP
series.
It will use new way to control the GPIO level, direction
and edge status.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/gpio/Kconfig|   7 +
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-mmp.c | 444 
 3 files changed, 452 insertions(+)
 create mode 100644 drivers/gpio/gpio-mmp.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 633ec21..c1e4e27 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -197,6 +197,13 @@ config GPIO_F7188X
  To compile this driver as a module, choose M here: the module will
  be called f7188x-gpio.
 
+config GPIO_MMP
+   bool MMP GPIO support
+   depends on ARCH_MMP
+   help
+ Say yes here to support the MMP GPIO device at 
PXA1088/PXA1908/PXA1928.
+ Comparing with PXA GPIO device, the IP of MMP GPIO changes a lot.
+
 config GPIO_MOXART
bool MOXART GPIO support
depends on ARCH_MOXART
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 81755f1..60a7cf5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
 obj-$(CONFIG_GPIO_MCP23S08)+= gpio-mcp23s08.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
+obj-$(CONFIG_GPIO_MMP) += gpio-mmp.o
 obj-$(CONFIG_GPIO_MOXART)  += gpio-moxart.o
 obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
diff --git a/drivers/gpio/gpio-mmp.c b/drivers/gpio/gpio-mmp.c
new file mode 100644
index 000..63e0766
--- /dev/null
+++ b/drivers/gpio/gpio-mmp.c
@@ -0,0 +1,444 @@
+/*
+ *  Copyright (C) 2014 Marvell International Ltd.
+ *
+ *  Generic MMP GPIO handling
+ *
+ * Chao Xie chao@marvell.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include linux/err.h
+#include linux/init.h
+#include linux/irq.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/gpio.h
+#include linux/clk.h
+#include linux/of_device.h
+#include linux/platform_device.h
+#include linux/module.h
+#include linux/irqdomain.h
+#include linux/irqchip/chained_irq.h
+#include linux/platform_data/gpio-mmp.h
+
+#define GPLR   0x0
+#define GPDR   0xc
+#define GPSR   0x18
+#define GPCR   0x24
+#define GRER   0x30
+#define GFER   0x3c
+#define GEDR   0x48
+#define GSDR   0x54
+#define GCDR   0x60
+#define GSRER  0x6c
+#define GCRER  0x78
+#define GSFER  0x84
+#define GCFER  0x90
+#define GAPMASK0x9c
+#define GCPMASK0xa8
+
+/* Bank will have 2^n GPIOes, and for mmp-gpio n = 5 */
+#define BANK_GPIO_ORDER5
+#define BANK_GPIO_NUMBER   (1  BANK_GPIO_ORDER)
+#define BANK_GPIO_MASK (BANK_GPIO_NUMBER - 1)
+
+#define mmp_gpio_to_bank_idx(gpio) ((gpio)  BANK_GPIO_ORDER)
+#define mmp_gpio_to_bank_offset(gpio)  ((gpio)  BANK_GPIO_MASK)
+#define mmp_bank_to_gpio(idx, offset)  (((idx)  BANK_GPIO_ORDER) \
+   | ((offset)  BANK_GPIO_MASK))
+
+struct mmp_gpio_bank {
+   void __iomem *reg_bank;
+   u32 irq_mask;
+   u32 irq_rising_edge;
+   u32 irq_falling_edge;
+};
+
+struct mmp_gpio_chip {
+   struct gpio_chip chip;
+   void __iomem *reg_base;
+   int irq;
+   struct irq_domain *domain;
+   unsigned int ngpio;
+   unsigned int nbank;
+   struct mmp_gpio_bank *banks;
+};
+
+static int mmp_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+
+   return irq_create_mapping(mmp_chip-domain, offset);
+}
+
+static int mmp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   mmp_chip-banks[mmp_gpio_to_bank_idx(offset)];
+   u32 bit = (1  mmp_gpio_to_bank_offset(offset));
+
+   writel(bit, bank-reg_bank + GCDR);
+
+   return 0;
+}
+
+static int mmp_gpio_direction_output(struct gpio_chip *chip,
+unsigned offset, int value)
+{
+   struct mmp_gpio_chip *mmp_chip =
+   container_of(chip, struct mmp_gpio_chip, chip);
+   struct mmp_gpio_bank *bank =
+   mmp_chip-banks[mmp_gpio_to_bank_idx(offset)];
+   u32 bit = (1  mmp_gpio_to_bank_offset(offset));
+
+   /* Set value first

[PATCH V2 00/13] clk: mmp: clock device tree support

2014-10-30 Thread Chao Xie
From: Chao Xie 

The patch set focuses at support device tree for clock.

The first part of the patches
  clk: mmp: add prefix "mmp" for structures defined for clk-frac
  clk: mmp: add spin lock for clk-frac
  clk: mmp: add init callback for clk-frac
  clk: mmp: move definiton of mmp_clk_frac to clk.h It enhances the clk-frac.

The second part of the patches
  clk: mmp: add clock type mix
  clk: mmp: add mmp private gate clock

The third part of the patches
  clk: mmp: add basic support functions for DT support
  clk: mmp: add reset support
  clk: mmp: add pxa168 DT support for clock driver
  clk: mmp: add pxa910 DT support for clock driver
  clk: mmp: add mmp2 DT support for clock driver
It add the device tree support for pxa168, pxa910 and mmp2.

V1 -> V2:
  Add reset support for the clocks that have reset bit.

Chao Xie (13):
  clk: mmp: add prefix "mmp" for structures defined for clk-frac
  clk: mmp: add spin lock for clk-frac
  clk: mmp: add init callback for clk-frac
  clk: mmp: move definiton of mmp_clk_frac to clk.h
  clk: mmp: add clock type mix
  clk: mmp: add mmp private gate clock
  clk: mmp: add basic support functions for DT support
  clk: mmp: add reset support
  clk: mmp: add pxa168 DT support for clock driver
  clk: mmp: add pxa910 DT support for clock driver
  clk: mmp: add mmp2 DT support for clock driver
  arm: mmp: Make all the dts file to be compiled by Makefile
  arm: mmp: Make use of the DT supported clock

 .../devicetree/bindings/clock/marvell,mmp2.txt |  21 +
 .../devicetree/bindings/clock/marvell,pxa168.txt   |  21 +
 .../devicetree/bindings/clock/marvell,pxa910.txt   |  21 +
 arch/arm/boot/dts/Makefile |   3 +
 arch/arm/boot/dts/mmp2-brownstone.dts  |   2 +-
 arch/arm/boot/dts/mmp2.dtsi|  29 +-
 arch/arm/boot/dts/pxa168-aspenite.dts  |   2 +-
 arch/arm/boot/dts/pxa168.dtsi  |  27 +-
 arch/arm/boot/dts/pxa910-dkb.dts   |   2 +-
 arch/arm/boot/dts/pxa910.dtsi  |  28 +-
 arch/arm/mach-mmp/Kconfig  |  12 +-
 arch/arm/mach-mmp/mmp-dt.c |  57 +--
 arch/arm/mach-mmp/mmp2-dt.c|  26 +-
 drivers/clk/mmp/Makefile   |   7 +-
 drivers/clk/mmp/clk-frac.c |  74 ++-
 drivers/clk/mmp/clk-gate.c | 133 ++
 drivers/clk/mmp/clk-mix.c  | 513 +
 drivers/clk/mmp/clk-mmp2.c |   6 +-
 drivers/clk/mmp/clk-of-mmp2.c  | 334 ++
 drivers/clk/mmp/clk-of-pxa168.c| 279 +++
 drivers/clk/mmp/clk-of-pxa910.c| 301 
 drivers/clk/mmp/clk-pxa168.c   |   6 +-
 drivers/clk/mmp/clk-pxa910.c   |   6 +-
 drivers/clk/mmp/clk.c  | 192 
 drivers/clk/mmp/clk.h  | 226 -
 drivers/clk/mmp/reset.c|  99 
 drivers/clk/mmp/reset.h|  31 ++
 include/dt-bindings/clock/marvell,mmp2.h   |  74 +++
 include/dt-bindings/clock/marvell,pxa168.h |  57 +++
 include/dt-bindings/clock/marvell,pxa910.h |  54 +++
 30 files changed, 2538 insertions(+), 105 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,mmp2.txt
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,pxa168.txt
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,pxa910.txt
 create mode 100644 drivers/clk/mmp/clk-gate.c
 create mode 100644 drivers/clk/mmp/clk-mix.c
 create mode 100644 drivers/clk/mmp/clk-of-mmp2.c
 create mode 100644 drivers/clk/mmp/clk-of-pxa168.c
 create mode 100644 drivers/clk/mmp/clk-of-pxa910.c
 create mode 100644 drivers/clk/mmp/clk.c
 create mode 100644 drivers/clk/mmp/reset.c
 create mode 100644 drivers/clk/mmp/reset.h
 create mode 100644 include/dt-bindings/clock/marvell,mmp2.h
 create mode 100644 include/dt-bindings/clock/marvell,pxa168.h
 create mode 100644 include/dt-bindings/clock/marvell,pxa910.h

-- 
1.8.3.2

--
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 V2 02/13] clk: mmp: add spin lock for clk-frac

2014-10-30 Thread Chao Xie
From: Chao Xie 

The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c   | 11 ++-
 drivers/clk/mmp/clk-mmp2.c   |  2 +-
 drivers/clk/mmp/clk-pxa168.c |  2 +-
 drivers/clk/mmp/clk-pxa910.c |  2 +-
 drivers/clk/mmp/clk.h|  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 3fbc9ca..e29d006 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -29,6 +29,7 @@ struct mmp_clk_factor {
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
+   spinlock_t *lock;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
+   unsigned long flags = 0;
 
for (i = 0; i < factor->ftbl_cnt; i++) {
prev_rate = rate;
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
if (i > 0)
i--;
 
+   if (factor->lock)
+   spin_lock_irqsave(factor->lock, flags);
+
val = readl_relaxed(factor->base);
 
val &= ~(masks->num_mask << masks->num_shift);
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
 
writel_relaxed(val, factor->base);
 
+   if (factor->lock)
+   spin_unlock_irqrestore(factor->lock, flags);
+
return 0;
 }
 
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
unsigned long flags, void __iomem *base,
struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl,
-   unsigned int ftbl_cnt)
+   unsigned int ftbl_cnt, spinlock_t *lock)
 {
struct mmp_clk_factor *factor;
struct clk_init_data init;
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
factor->ftbl = ftbl;
factor->ftbl_cnt = ftbl_cnt;
factor->hw.init = 
+   factor->lock = lock;
 
init.name = name;
init.ops = _factor_ops;
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 7083f12..5c90a42 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 75266ac..93e967c 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index f817999..993abcd 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll =  mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 3fe92be..b71b717 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name,
 extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsig

[PATCH V2 07/13] clk: mmp: add basic support functions for DT support

2014-10-30 Thread Chao Xie
From: Chao Xie 

In order to support DT for mmp SOC clocks, it defines
some basic APIs which are shared by all mmp SOC clock
units.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/Makefile |   2 +-
 drivers/clk/mmp/clk.c| 192 +++
 drivers/clk/mmp/clk.h| 106 +-
 3 files changed, 298 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/mmp/clk.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 2855f7b..32b5b90 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
new file mode 100644
index 000..cf038ef
--- /dev/null
+++ b/drivers/clk/mmp/clk.c
@@ -0,0 +1,192 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+
+void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
+   int nr_clks)
+{
+   static struct clk **clk_table;
+
+   clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
+   if (!clk_table)
+   return;
+
+   unit->clk_table = clk_table;
+   unit->nr_clks = nr_clks;
+   unit->clk_data.clks = clk_table;
+   unit->clk_data.clk_num = nr_clks;
+   of_clk_add_provider(np, of_clk_src_onecell_get, >clk_data);
+}
+
+void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_fixed_rate_clk *clks,
+   int size)
+{
+   int i;
+   struct clk *clk;
+
+   for (i = 0; i < size; i++) {
+   clk = clk_register_fixed_rate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   clks[i].fixed_rate);
+   if (IS_ERR(clk)) {
+   pr_err("%s: failed to register clock %s\n",
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit->clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_fixed_factor_clk *clks,
+   int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   clk = clk_register_fixed_factor(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags, clks[i].mult,
+   clks[i].div);
+   if (IS_ERR(clk)) {
+   pr_err("%s: failed to register clock %s\n",
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit->clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_general_gate_clk *clks,
+   void __iomem *base, int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   clk = clk_register_gate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   base + clks[i].offset,
+   clks[i].bit_idx,
+   clks[i].gate_flags,
+   clks[i].lock);
+
+   if (IS_ERR(clk)) {
+   pr_err("%s: failed to register clock %s\n",
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit->clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_gate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_gate_clk *clks,
+   void __iomem *base, int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   clk = mmp_clk_register_gate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   base + clks[i].offset,
+   clks[i].mask,
+   clks[i].val_enable,
+

[PATCH V2 01/13] clk: mmp: add prefix "mmp" for structures defined for clk-frac

2014-10-30 Thread Chao Xie
From: Chao Xie 

The structures defined for clk-frac will be used out side
of clk-frac.c.
To avoid conflicts, add prefix "mmp" for these structures'
name.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c   | 23 ---
 drivers/clk/mmp/clk-mmp2.c   |  4 ++--
 drivers/clk/mmp/clk-pxa168.c |  4 ++--
 drivers/clk/mmp/clk-pxa910.c |  4 ++--
 drivers/clk/mmp/clk.h|  8 
 5 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 23a56f5..3fbc9ca 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -22,19 +22,19 @@
  * numerator/denominator = Fin / (Fout * factor)
  */
 
-#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw)
-struct clk_factor {
+#define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
+struct mmp_clk_factor {
struct clk_hw   hw;
void __iomem*base;
-   struct clk_factor_masks *masks;
-   struct clk_factor_tbl   *ftbl;
+   struct mmp_clk_factor_masks *masks;
+   struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
unsigned long rate = 0, prev_rate;
int i;
 
@@ -58,8 +58,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned 
long drate,
 static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
-   struct clk_factor_masks *masks = factor->masks;
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor->masks;
unsigned int val, num, den;
 
val = readl_relaxed(factor->base);
@@ -81,8 +81,8 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
 static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
-   struct clk_factor_masks *masks = factor->masks;
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor->masks;
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
@@ -118,10 +118,11 @@ static struct clk_ops clk_factor_ops = {
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
unsigned long flags, void __iomem *base,
-   struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl,
+   struct mmp_clk_factor_masks *masks,
+   struct mmp_clk_factor_tbl *ftbl,
unsigned int ftbl_cnt)
 {
-   struct clk_factor *factor;
+   struct mmp_clk_factor *factor;
struct clk_init_data init;
struct clk *clk;
 
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index b2721ca..7083f12 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -54,7 +54,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 14634, .den = 2165},/*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
{.num = 9679, .den = 5728}, /*58.9824MHZ */
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 014396b..75266ac 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -47,7 +47,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 8125, .den = 1536}, /*14.745MHZ */
 };
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index 9efc6a4..f817999 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -45,7 +45,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -53

[PATCH V2 03/13] clk: mmp: add init callback for clk-frac

2014-10-30 Thread Chao Xie
From: Chao Xie 

For the clk-frac, we need to make sure that the initial
clock rate is one item of the table.
If it is not, we use the first item in the table by default.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index e29d006..1876d2c 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -118,10 +118,50 @@ static int clk_factor_set_rate(struct clk_hw *hw, 
unsigned long drate,
return 0;
 }
 
+void clk_factor_init(struct clk_hw *hw)
+{
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor->masks;
+   u32 val, num, den;
+   int i;
+   unsigned long flags = 0;
+
+   if (factor->lock)
+   spin_lock_irqsave(factor->lock, flags);
+
+   val = readl(factor->base);
+
+   /* calculate numerator */
+   num = (val >> masks->num_shift) & masks->num_mask;
+
+   /* calculate denominator */
+   den = (val >> masks->den_shift) & masks->den_mask;
+
+   for (i = 0; i < factor->ftbl_cnt; i++)
+   if (den == factor->ftbl[i].den && num == factor->ftbl[i].num)
+   break;
+
+   if (i >= factor->ftbl_cnt) {
+   val &= ~(masks->num_mask << masks->num_shift);
+   val |= (factor->ftbl[0].num & masks->num_mask) <<
+   masks->num_shift;
+
+   val &= ~(masks->den_mask << masks->den_shift);
+   val |= (factor->ftbl[0].den & masks->den_mask) <<
+   masks->den_shift;
+
+   writel(val, factor->base);
+   }
+
+   if (factor->lock)
+   spin_unlock_irqrestore(factor->lock, flags);
+}
+
 static struct clk_ops clk_factor_ops = {
.recalc_rate = clk_factor_recalc_rate,
.round_rate = clk_factor_round_rate,
.set_rate = clk_factor_set_rate,
+   .init = clk_factor_init,
 };
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
-- 
1.8.3.2

--
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 V2 04/13] clk: mmp: move definiton of mmp_clk_frac to clk.h

2014-10-30 Thread Chao Xie
From: Chao Xie 

Move the definition of structure of mmp_clk_frac to
clk.h.
So device tree support can use this structure.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c |  8 
 drivers/clk/mmp/clk.h  | 32 ++--
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 1876d2c..eeba52c 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -23,14 +23,6 @@
  */
 
 #define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
-struct mmp_clk_factor {
-   struct clk_hw   hw;
-   void __iomem*base;
-   struct mmp_clk_factor_masks *masks;
-   struct mmp_clk_factor_tbl   *ftbl;
-   unsigned intftbl_cnt;
-   spinlock_t *lock;
-};
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index b71b717..d267639 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -7,12 +7,14 @@
 #define APBC_NO_BUS_CTRL   BIT(0)
 #define APBC_POWER_CTRLBIT(1)
 
+
+/* Clock type "factor" */
 struct mmp_clk_factor_masks {
-   unsigned intfactor;
-   unsigned intnum_mask;
-   unsigned intden_mask;
-   unsigned intnum_shift;
-   unsigned intden_shift;
+   unsigned int factor;
+   unsigned int num_mask;
+   unsigned int den_mask;
+   unsigned int num_shift;
+   unsigned int den_shift;
 };
 
 struct mmp_clk_factor_tbl {
@@ -20,6 +22,21 @@ struct mmp_clk_factor_tbl {
unsigned int den;
 };
 
+struct mmp_clk_factor {
+   struct clk_hw hw;
+   void __iomem *base;
+   struct mmp_clk_factor_masks *masks;
+   struct mmp_clk_factor_tbl *ftbl;
+   unsigned int ftbl_cnt;
+   spinlock_t *lock;
+};
+
+extern struct clk *mmp_clk_register_factor(const char *name,
+   const char *parent_name, unsigned long flags,
+   void __iomem *base, struct mmp_clk_factor_masks *masks,
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t *lock);
+
 extern struct clk *mmp_clk_register_pll2(const char *name,
const char *parent_name, unsigned long flags);
 extern struct clk *mmp_clk_register_apbc(const char *name,
@@ -28,9 +45,4 @@ extern struct clk *mmp_clk_register_apbc(const char *name,
 extern struct clk *mmp_clk_register_apmu(const char *name,
const char *parent_name, void __iomem *base, u32 enable_mask,
spinlock_t *lock);
-extern struct clk *mmp_clk_register_factor(const char *name,
-   const char *parent_name, unsigned long flags,
-   void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
-   spinlock_t *lock);
 #endif
-- 
1.8.3.2

--
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 V2 06/13] clk: mmp: add mmp private gate clock

2014-10-30 Thread Chao Xie
From: Chao Xie 

Some SOCes have this kind of the gate clock
1. There are some bits to control the gate not only one bit.
2. It is not always that "1" is to enable while "0" is to disable
   when write register.

So we have to define the "mask", "enable_val", "disable_val" for
this kind of gate clock.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/Makefile   |   2 +-
 drivers/clk/mmp/clk-gate.c | 133 +
 drivers/clk/mmp/clk.h  |  21 +++
 3 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/clk-gate.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 8bfee860..2855f7b 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
new file mode 100644
index 000..adbd9d6
--- /dev/null
+++ b/drivers/clk/mmp/clk-gate.c
@@ -0,0 +1,133 @@
+/*
+ * mmp gate clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+
+/*
+ * Some clocks will have mutiple bits to enable the clocks, and
+ * the bits to disable the clock is not same as enabling bits.
+ */
+
+#define to_clk_mmp_gate(hw)container_of(hw, struct mmp_clk_gate, hw)
+
+static int mmp_clk_gate_enable(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   struct clk *clk = hw->clk;
+   unsigned long flags = 0;
+   unsigned long rate;
+   u32 tmp;
+
+   if (gate->lock)
+   spin_lock_irqsave(gate->lock, flags);
+
+   tmp = readl(gate->reg);
+   tmp &= ~gate->mask;
+   tmp |= gate->val_enable;
+   writel(tmp, gate->reg);
+
+   if (gate->lock)
+   spin_unlock_irqrestore(gate->lock, flags);
+
+   if (gate->flags & MMP_CLK_GATE_NEED_DELAY) {
+   rate = __clk_get_rate(clk);
+   /* Need delay 2 cycles. */
+   udelay(200/rate);
+   }
+
+   return 0;
+}
+
+static void mmp_clk_gate_disable(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   unsigned long flags = 0;
+   u32 tmp;
+
+   if (gate->lock)
+   spin_lock_irqsave(gate->lock, flags);
+
+   tmp = readl(gate->reg);
+   tmp &= ~gate->mask;
+   tmp |= gate->val_disable;
+   writel(tmp, gate->reg);
+
+   if (gate->lock)
+   spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   unsigned long flags = 0;
+   u32 tmp;
+
+   if (gate->lock)
+   spin_lock_irqsave(gate->lock, flags);
+
+   tmp = readl(gate->reg);
+
+   if (gate->lock)
+   spin_unlock_irqrestore(gate->lock, flags);
+
+   return (tmp & gate->mask) == gate->val_enable;
+}
+
+const struct clk_ops mmp_clk_gate_ops = {
+   .enable = mmp_clk_gate_enable,
+   .disable = mmp_clk_gate_disable,
+   .is_enabled = mmp_clk_gate_is_enabled,
+};
+
+struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
+   const char *parent_name, unsigned long flags,
+   void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
+   unsigned int gate_flags, spinlock_t *lock)
+{
+   struct mmp_clk_gate *gate;
+   struct clk *clk;
+   struct clk_init_data init;
+
+   /* allocate the gate */
+   gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+   if (!gate) {
+   pr_err("%s:%s could not allocate gate clk\n", __func__, name);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   init.name = name;
+   init.ops = _clk_gate_ops;
+   init.flags = flags | CLK_IS_BASIC;
+   init.parent_names = (parent_name ? _name : NULL);
+   init.num_parents = (parent_name ? 1 : 0);
+
+   /* struct clk_gate assignments */
+   gate->reg = reg;
+   gate->mask = mask;
+   gate->val_enable = val_enable;
+   gate->val_disable = val_disable;
+   gate->flags = gate_flags;
+   gate->lock = lock;
+   gate->hw.init = 
+
+   clk = clk_register(dev, >hw);
+
+   if (IS_ERR(clk))
+   kfree(gate);
+
+   return clk;
+}
diff --git a/drivers/clk/mmp/

[PATCH V2 08/13] clk: mmp: add reset support

2014-10-30 Thread Chao Xie
From: Chao Xie 

Some clock control regsiter has bit to reset the cotroller.
So before enable the clock, we need deassert the reset pin.
Make use of reset controller framework to export reset interface
for device drivers, then device driver can control the reset action.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/Makefile |  2 +
 drivers/clk/mmp/reset.c  | 99 
 drivers/clk/mmp/reset.h  | 31 +++
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/clk/mmp/reset.c
 create mode 100644 drivers/clk/mmp/reset.h

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 32b5b90..2573d7c 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -4,6 +4,8 @@
 
 obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
+obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
 obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
diff --git a/drivers/clk/mmp/reset.c b/drivers/clk/mmp/reset.c
new file mode 100644
index 000..b54da1f
--- /dev/null
+++ b/drivers/clk/mmp/reset.c
@@ -0,0 +1,99 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "reset.h"
+
+#define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, 
rcdev)
+
+static int mmp_of_reset_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+   struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+   struct mmp_clk_reset_cell *cell;
+   int i;
+
+   if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
+   return -EINVAL;
+
+   for (i = 0; i < rcdev->nr_resets; i++) {
+   cell = >cells[i];
+   if (cell->clk_id == reset_spec->args[0])
+   break;
+   }
+
+   if (i == rcdev->nr_resets)
+   return -EINVAL;
+
+   return i;
+}
+
+static int mmp_clk_reset_assert(struct reset_controller_dev *rcdev,
+   unsigned long id)
+{
+   struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+   struct mmp_clk_reset_cell *cell;
+   unsigned long flags = 0;
+   u32 val;
+
+   cell = >cells[id];
+   if (cell->lock)
+   spin_lock_irqsave(cell->lock, flags);
+
+   val = readl(cell->reg);
+   val |= cell->bits;
+   writel(val, cell->reg);
+
+   if (cell->lock)
+   spin_unlock_irqrestore(cell->lock, flags);
+
+   return 0;
+}
+
+static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev,
+   unsigned long id)
+{
+   struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+   struct mmp_clk_reset_cell *cell;
+   unsigned long flags = 0;
+   u32 val;
+
+   cell = >cells[id];
+   if (cell->lock)
+   spin_lock_irqsave(cell->lock, flags);
+
+   val = readl(cell->reg);
+   val &= ~cell->bits;
+   writel(val, cell->reg);
+
+   if (cell->lock)
+   spin_unlock_irqrestore(cell->lock, flags);
+
+   return 0;
+}
+
+static struct reset_control_ops mmp_clk_reset_ops = {
+   .assert = mmp_clk_reset_assert,
+   .deassert   = mmp_clk_reset_deassert,
+};
+
+void mmp_clk_reset_register(struct device_node *np,
+   struct mmp_clk_reset_cell *cells, int nr_resets)
+{
+   struct mmp_clk_reset_unit *unit;
+
+   unit = kzalloc(sizeof(*unit), GFP_KERNEL);
+   if (!unit)
+   return;
+
+   unit->cells = cells;
+   unit->rcdev.of_reset_n_cells = 1;
+   unit->rcdev.nr_resets = nr_resets;
+   unit->rcdev.ops = _clk_reset_ops;
+   unit->rcdev.of_node = np;
+   unit->rcdev.of_xlate = mmp_of_reset_xlate;
+
+   reset_controller_register(>rcdev);
+}
diff --git a/drivers/clk/mmp/reset.h b/drivers/clk/mmp/reset.h
new file mode 100644
index 000..be8b1a7
--- /dev/null
+++ b/drivers/clk/mmp/reset.h
@@ -0,0 +1,31 @@
+#ifndef __MACH_MMP_CLK_RESET_H
+#define __MACH_MMP_CLK_RESET_H
+
+#include 
+
+#define MMP_RESET_INVERT   1
+
+struct mmp_clk_reset_cell {
+   unsigned int clk_id;
+   void __iomem *reg;
+   u32 bits;
+   unsigned int flags;
+   spinlock_t *lock;
+};
+
+struct mmp_clk_reset_unit {
+   struct reset_controller_dev rcdev;
+   struct mmp_clk_reset_cell *cells;
+};
+
+#ifdef CONFIG_RESET_CONTROLLER
+void mmp_clk_reset_register(struct device_node *np,
+   struct mmp_clk_reset_cell *cells, int nr_resets);
+#else
+static inline void mmp_clk_reset_register(struct device_node *np,
+   struct mmp_clk_reset_cell *cells, int nr_resets)
+{
+}
+#endif
+
+#endif
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a messag

[PATCH V2 12/13] arm: mmp: Make all the dts file to be compiled by Makefile

2014-10-30 Thread Chao Xie
From: Chao Xie 

Add items in arch/arm/boot/dt/Makefile to compile the dtb
for mach-mmp.
Change the dts and dtsi file to use #include instead of \include\

Signed-off-by: Chao Xie 
---
 arch/arm/boot/dts/Makefile| 3 +++
 arch/arm/boot/dts/mmp2-brownstone.dts | 2 +-
 arch/arm/boot/dts/mmp2.dtsi   | 2 +-
 arch/arm/boot/dts/pxa168-aspenite.dts | 2 +-
 arch/arm/boot/dts/pxa168.dtsi | 2 +-
 arch/arm/boot/dts/pxa910-dkb.dts  | 2 +-
 arch/arm/boot/dts/pxa910.dtsi | 2 +-
 7 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b8c5cd3..f8f7613 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -159,6 +159,9 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
kirkwood-ts419-6282.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
+   pxa910-dkb.dtb \
+   mmp2-brownstone.dtb
 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
imx25-eukrea-mbimxsd25-baseboard.dtb \
diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts 
b/arch/arm/boot/dts/mmp2-brownstone.dts
index 7f70a39..350208c 100644
--- a/arch/arm/boot/dts/mmp2-brownstone.dts
+++ b/arch/arm/boot/dts/mmp2-brownstone.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "mmp2.dtsi"
+#include "mmp2.dtsi"
 
 / {
model = "Marvell MMP2 Brownstone Development Board";
diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 4e8b08c..e44f996 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
aliases {
diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts 
b/arch/arm/boot/dts/pxa168-aspenite.dts
index e762fac..0a988b3 100644
--- a/arch/arm/boot/dts/pxa168-aspenite.dts
+++ b/arch/arm/boot/dts/pxa168-aspenite.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "pxa168.dtsi"
+#include "pxa168.dtsi"
 
 / {
model = "Marvell PXA168 Aspenite Development Board";
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index 975dad2..bfcbdef 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
aliases {
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..c82f281 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "pxa910.dtsi"
+#include "pxa910.dtsi"
 
 / {
model = "Marvell PXA910 DKB Development Board";
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 0247c62..884c6e8 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
aliases {
-- 
1.8.3.2

--
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 V2 11/13] clk: mmp: add mmp2 DT support for clock driver

2014-10-30 Thread Chao Xie
From: Chao Xie 

It adds the DT support for mmp2 clock subsystem.

Signed-off-by: Chao Xie 
---
 .../devicetree/bindings/clock/marvell,mmp2.txt |  21 ++
 drivers/clk/mmp/Makefile   |   1 +
 drivers/clk/mmp/clk-of-mmp2.c  | 334 +
 include/dt-bindings/clock/marvell,mmp2.h   |  74 +
 4 files changed, 430 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,mmp2.txt
 create mode 100644 drivers/clk/mmp/clk-of-mmp2.c
 create mode 100644 include/dt-bindings/clock/marvell,mmp2.h

diff --git a/Documentation/devicetree/bindings/clock/marvell,mmp2.txt 
b/Documentation/devicetree/bindings/clock/marvell,mmp2.txt
new file mode 100644
index 000..af376a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell,mmp2.txt
@@ -0,0 +1,21 @@
+* Marvell MMP2 Clock Controller
+
+The MMP2 clock subsystem generates and supplies clock to various
+controllers within the MMP2 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,mmp2-clock" - controller compatible with MMP2 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc". So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in .
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 947cd74..3caaf7c 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -7,6 +7,7 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o 
clk.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 
 obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
+obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
new file mode 100644
index 000..2cbc2b4
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -0,0 +1,334 @@
+/*
+ * mmp2 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "reset.h"
+
+#define APBC_RTC   0x0
+#define APBC_TWSI0 0x4
+#define APBC_TWSI1 0x8
+#define APBC_TWSI2 0xc
+#define APBC_TWSI3 0x10
+#define APBC_TWSI4 0x7c
+#define APBC_TWSI5 0x80
+#define APBC_KPC   0x18
+#define APBC_UART0 0x2c
+#define APBC_UART1 0x30
+#define APBC_UART2 0x34
+#define APBC_UART3 0x88
+#define APBC_GPIO  0x38
+#define APBC_PWM0  0x3c
+#define APBC_PWM1  0x40
+#define APBC_PWM2  0x44
+#define APBC_PWM3  0x48
+#define APBC_SSP0  0x50
+#define APBC_SSP1  0x54
+#define APBC_SSP2  0x58
+#define APBC_SSP3  0x5c
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_SDH2  0xe8
+#define APMU_SDH3  0xec
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_DISP1 0x110
+#define APMU_CCIC0 0x50
+#define APMU_CCIC1 0xf4
+#define MPMU_UART_PLL  0x14
+
+struct mmp2_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {MMP2_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+   {MMP2_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
+   {MMP2_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 8},
+   {MMP2_CLK_PLL2, "pll2", NULL, CLK_IS_ROOT, 96000},
+   {MMP2_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 48000},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {MMP2_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+   {MMP2_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+   {MMP2_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+   {MMP2_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+   {MMP2_CLK_PLL1_20, "pll1_20", "pll1_4", 1, 5, 0},
+   {MMP2_CLK_PLL1_3, "pll1_3", "pll1", 1, 3, 0},
+   {MMP2_CLK_PLL1_6, "pll1_6", "pll1_3", 1, 2, 0},
+   {MMP2_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+   {MMP2_CLK_PLL2_2, "pll2_2", "pll2", 1, 2, 0},
+   {MMP2_C

[PATCH V2 10/13] clk: mmp: add pxa910 DT support for clock driver

2014-10-30 Thread Chao Xie
From: Chao Xie 

It adds the DT support for pxa910 clock subsystem.

Signed-off-by: Chao Xie 
---
 .../devicetree/bindings/clock/marvell,pxa910.txt   |  21 ++
 drivers/clk/mmp/Makefile   |   2 +-
 drivers/clk/mmp/clk-of-pxa910.c| 301 +
 include/dt-bindings/clock/marvell,pxa910.h |  54 
 4 files changed, 377 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,pxa910.txt
 create mode 100644 drivers/clk/mmp/clk-of-pxa910.c
 create mode 100644 include/dt-bindings/clock/marvell,pxa910.h

diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa910.txt 
b/Documentation/devicetree/bindings/clock/marvell,pxa910.txt
new file mode 100644
index 000..d9f41f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell,pxa910.txt
@@ -0,0 +1,21 @@
+* Marvell PXA910 Clock Controller
+
+The PXA910 clock subsystem generates and supplies clock to various
+controllers within the PXA910 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,pxa910-clock" - controller compatible with PXA910 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 4 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc", "apbcp". So four reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in .
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 733acc7..947cd74 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -6,7 +6,7 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o 
clk.o
 
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 
-obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
new file mode 100644
index 000..5e3c80d
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -0,0 +1,301 @@
+/*
+ * pxa910 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "reset.h"
+
+#define APBC_RTC   0x28
+#define APBC_TWSI0 0x2c
+#define APBC_KPC   0x18
+#define APBC_UART0 0x0
+#define APBC_UART1 0x4
+#define APBC_GPIO  0x8
+#define APBC_PWM0  0xc
+#define APBC_PWM1  0x10
+#define APBC_PWM2  0x14
+#define APBC_PWM3  0x18
+#define APBC_SSP0  0x1c
+#define APBC_SSP1  0x20
+#define APBC_SSP2  0x4c
+#define APBCP_TWSI10x28
+#define APBCP_UART20x1c
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_CCIC0 0x50
+#define APMU_DFC   0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa910_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+   void __iomem *apbcp_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+   {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
+   {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 62400},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {PXA910_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+   {PXA910_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+   {PXA910_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+   {PXA910_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+   {PXA910_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0},
+   {PXA910_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+   {PXA910_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
+   {PXA910_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
+   {PXA910_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
+   {PXA910_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
+   {PXA910_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
+   {PXA910_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
+   {PXA910_CLK_PLL1_3_16, "p

[PATCH V2 09/13] clk: mmp: add pxa168 DT support for clock driver

2014-10-30 Thread Chao Xie
From: Chao Xie 

It adds the DT support for pxa168 clock subsystem.

Signed-off-by: Chao Xie 
---
 .../devicetree/bindings/clock/marvell,pxa168.txt   |  21 ++
 drivers/clk/mmp/Makefile   |   2 +
 drivers/clk/mmp/clk-of-pxa168.c| 279 +
 include/dt-bindings/clock/marvell,pxa168.h |  57 +
 4 files changed, 359 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,pxa168.txt
 create mode 100644 drivers/clk/mmp/clk-of-pxa168.c
 create mode 100644 include/dt-bindings/clock/marvell,pxa168.h

diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa168.txt 
b/Documentation/devicetree/bindings/clock/marvell,pxa168.txt
new file mode 100644
index 000..c62eb1d
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell,pxa168.txt
@@ -0,0 +1,21 @@
+* Marvell PXA168 Clock Controller
+
+The PXA168 clock subsystem generates and supplies clock to various
+controllers within the PXA168 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,pxa168-clock" - controller compatible with PXA168 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc". So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in .
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 2573d7c..733acc7 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -6,6 +6,8 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o 
clk.o
 
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o
+
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
 obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
new file mode 100644
index 000..5b1810d
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -0,0 +1,279 @@
+/*
+ * pxa168 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "reset.h"
+
+#define APBC_RTC   0x28
+#define APBC_TWSI0 0x2c
+#define APBC_KPC   0x30
+#define APBC_UART0 0x0
+#define APBC_UART1 0x4
+#define APBC_GPIO  0x8
+#define APBC_PWM0  0xc
+#define APBC_PWM1  0x10
+#define APBC_PWM2  0x14
+#define APBC_PWM3  0x18
+#define APBC_SSP0  0x81c
+#define APBC_SSP1  0x820
+#define APBC_SSP2  0x84c
+#define APBC_SSP3  0x858
+#define APBC_SSP4  0x85c
+#define APBC_TWSI1 0x6c
+#define APBC_UART2 0x70
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_CCIC0 0x50
+#define APMU_DFC   0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa168_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+   {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
+   {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 62400},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {PXA168_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+   {PXA168_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+   {PXA168_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+   {PXA168_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+   {PXA168_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0},
+   {PXA168_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+   {PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
+   {PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
+   {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
+   {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
+   {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
+   {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
+   {PXA168_CLK_PLL1_3_16, "pll1_3_16", "pll1",

[PATCH V2 13/13] arm: mmp: Make use of the DT supported clock

2014-10-30 Thread Chao Xie
From: Chao Xie 

Change the dtsi and dts file, soc initialization code to make
use of DT support clock.
So now in the code we do only need call of_clk_init to initialize
the clocks.

Signed-off-by: Chao Xie 
---
 arch/arm/boot/dts/mmp2.dtsi   | 27 
 arch/arm/boot/dts/pxa168.dtsi | 25 +++
 arch/arm/boot/dts/pxa910.dtsi | 26 
 arch/arm/mach-mmp/Kconfig | 12 -
 arch/arm/mach-mmp/mmp-dt.c| 57 ++-
 arch/arm/mach-mmp/mmp2-dt.c   | 26 +++-
 6 files changed, 111 insertions(+), 62 deletions(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index e44f996..766bbb8 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -8,6 +8,7 @@
  */
 
 #include "skeleton.dtsi"
+#include 
 
 / {
aliases {
@@ -135,6 +136,8 @@
compatible = "mrvl,mmp-uart";
reg = <0xd403 0x1000>;
interrupts = <27>;
+   clocks = <_clocks MMP2_CLK_UART0>;
+   resets = <_clocks MMP2_CLK_UART0>;
status = "disabled";
};
 
@@ -142,6 +145,8 @@
compatible = "mrvl,mmp-uart";
reg = <0xd4017000 0x1000>;
interrupts = <28>;
+   clocks = <_clocks MMP2_CLK_UART1>;
+   resets = <_clocks MMP2_CLK_UART1>;
status = "disabled";
};
 
@@ -149,6 +154,8 @@
compatible = "mrvl,mmp-uart";
reg = <0xd4018000 0x1000>;
interrupts = <24>;
+   clocks = <_clocks MMP2_CLK_UART2>;
+   resets = <_clocks MMP2_CLK_UART2>;
status = "disabled";
};
 
@@ -156,6 +163,8 @@
compatible = "mrvl,mmp-uart";
reg = <0xd4016000 0x1000>;
interrupts = <46>;
+   clocks = <_clocks MMP2_CLK_UART3>;
+   resets = <_clocks MMP2_CLK_UART3>;
status = "disabled";
};
 
@@ -168,6 +177,8 @@
#gpio-cells = <2>;
interrupts = <49>;
interrupt-names = "gpio_mux";
+   clocks = <_clocks MMP2_CLK_GPIO>;
+   resets = <_clocks MMP2_CLK_GPIO>;
interrupt-controller;
#interrupt-cells = <1>;
ranges;
@@ -201,6 +212,8 @@
compatible = "mrvl,mmp-twsi";
reg = <0xd4011000 0x1000>;
interrupts = <7>;
+   clocks = <_clocks MMP2_CLK_TWSI0>;
+   resets = <_clocks MMP2_CLK_TWSI0>;
#address-cells = <1>;
#size-cells = <0>;
mrvl,i2c-fast-mode;
@@ -211,6 +224,8 @@
compatible = "mrvl,mmp-twsi";
reg = <0xd4025000 0x1000>;
interrupts = <58>;
+   clocks = <_clocks MMP2_CLK_TWSI1>;
+   resets = <_clocks MMP2_CLK_TWSI1>;
status = "disabled";
};
 
@@ -220,8 +235,20 @@
interrupts = <1 0>;
interrupt-names = "rtc 1Hz", "rtc alarm";
interrupt-parent = <>;
+   clocks = <_clocks MMP2_CLK_RTC>;
+   resets = <_clocks MMP2_CLK_RTC>;
status = "disabled";
};
};
+
+   soc_clocks: clocks{
+   compatible = "marvell,mmp2-clock";
+   reg = <0xd405 0x1000>,
+ <0xd4282800 0x400>,
+ <0xd4015000 0x1000>;
+   reg-names = "mpmu", 

[PATCH V2 05/13] clk: mmp: add clock type mix

2014-10-30 Thread Chao Xie
From: Chao Xie 

The clock type mix is a kind of clock combines "div" and "mux".
This kind of clock can not allow to change div first then
mux or change mux first or div.
The reason is
1. Some clock has frequency change bit. Each time want to change
   the frequency, there are some operations based on this bit, and
   these operations are time-cost.
   Seperating div and mux change will make the process longer, and
   waste more time.
2. Seperting the div and mux may generate middle clock that the
   peripharals do not support. It may make the peripharals hang.

There are three kinds of this type of clock in all SOCes.
1. The clock has bit to trigger the frequency change.
2. Same as #1, but the operations for the bit is different
3. Do not have frequency change bit.

So this type of clock has implemented the callbacks
->determine_rate
->set_rate_and_parent
These callbacks can help to change the div and mux together.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/Makefile  |   2 +-
 drivers/clk/mmp/clk-mix.c | 513 ++
 drivers/clk/mmp/clk.h |  66 ++
 3 files changed, 580 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/clk-mix.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 392d780..8bfee860 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c
new file mode 100644
index 000..b79742c
--- /dev/null
+++ b/drivers/clk/mmp/clk-mix.c
@@ -0,0 +1,513 @@
+/*
+ * mmp mix(div and mux) clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+
+/*
+ * The mix clock is a clock combined mux and div type clock.
+ * Because the div field and mux field need to be set at same
+ * time, we can not divide it into 2 types of clock
+ */
+
+#define to_clk_mix(hw) container_of(hw, struct mmp_clk_mix, hw)
+
+static unsigned int _get_maxdiv(struct mmp_clk_mix *mix)
+{
+   unsigned int div_mask = (1 << mix->reg_info.width_div) - 1;
+   unsigned int maxdiv = 0;
+   struct clk_div_table *clkt;
+
+   if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+   return div_mask;
+   if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+   return 1 << div_mask;
+   if (mix->div_table) {
+   for (clkt = mix->div_table; clkt->div; clkt++)
+   if (clkt->div > maxdiv)
+   maxdiv = clkt->div;
+   return maxdiv;
+   }
+   return div_mask + 1;
+}
+
+static unsigned int _get_div(struct mmp_clk_mix *mix, unsigned int val)
+{
+   struct clk_div_table *clkt;
+
+   if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+   return val;
+   if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+   return 1 << val;
+   if (mix->div_table) {
+   for (clkt = mix->div_table; clkt->div; clkt++)
+   if (clkt->val == val)
+   return clkt->div;
+   if (clkt->div == 0)
+   return 0;
+   }
+   return val + 1;
+}
+
+static unsigned int _get_mux(struct mmp_clk_mix *mix, unsigned int val)
+{
+   int num_parents = __clk_get_num_parents(mix->hw.clk);
+   int i;
+
+   if (mix->mux_flags & CLK_MUX_INDEX_BIT)
+   return ffs(val) - 1;
+   if (mix->mux_flags & CLK_MUX_INDEX_ONE)
+   return val - 1;
+   if (mix->mux_table) {
+   for (i = 0; i < num_parents; i++)
+   if (mix->mux_table[i] == val)
+   return i;
+   if (i == num_parents)
+   return 0;
+   }
+
+   return val;
+}
+static unsigned int _get_div_val(struct mmp_clk_mix *mix, unsigned int div)
+{
+   struct clk_div_table *clkt;
+
+   if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+   return div;
+   if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+   return __ffs(div);
+   if (mix->div_table) {
+   for (clkt = mix->div_table; clkt->div; clkt++)
+   if (clkt->div == div)
+   return clkt->val;
+   if (clkt->div == 0)
+   return 0;
+   }
+
+   

[PATCH V2 13/13] arm: mmp: Make use of the DT supported clock

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

Change the dtsi and dts file, soc initialization code to make
use of DT support clock.
So now in the code we do only need call of_clk_init to initialize
the clocks.

Signed-off-by: Chao Xie chao@marvell.com
---
 arch/arm/boot/dts/mmp2.dtsi   | 27 
 arch/arm/boot/dts/pxa168.dtsi | 25 +++
 arch/arm/boot/dts/pxa910.dtsi | 26 
 arch/arm/mach-mmp/Kconfig | 12 -
 arch/arm/mach-mmp/mmp-dt.c| 57 ++-
 arch/arm/mach-mmp/mmp2-dt.c   | 26 +++-
 6 files changed, 111 insertions(+), 62 deletions(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index e44f996..766bbb8 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -8,6 +8,7 @@
  */
 
 #include skeleton.dtsi
+#include dt-bindings/clock/marvell,mmp2.h
 
 / {
aliases {
@@ -135,6 +136,8 @@
compatible = mrvl,mmp-uart;
reg = 0xd403 0x1000;
interrupts = 27;
+   clocks = soc_clocks MMP2_CLK_UART0;
+   resets = soc_clocks MMP2_CLK_UART0;
status = disabled;
};
 
@@ -142,6 +145,8 @@
compatible = mrvl,mmp-uart;
reg = 0xd4017000 0x1000;
interrupts = 28;
+   clocks = soc_clocks MMP2_CLK_UART1;
+   resets = soc_clocks MMP2_CLK_UART1;
status = disabled;
};
 
@@ -149,6 +154,8 @@
compatible = mrvl,mmp-uart;
reg = 0xd4018000 0x1000;
interrupts = 24;
+   clocks = soc_clocks MMP2_CLK_UART2;
+   resets = soc_clocks MMP2_CLK_UART2;
status = disabled;
};
 
@@ -156,6 +163,8 @@
compatible = mrvl,mmp-uart;
reg = 0xd4016000 0x1000;
interrupts = 46;
+   clocks = soc_clocks MMP2_CLK_UART3;
+   resets = soc_clocks MMP2_CLK_UART3;
status = disabled;
};
 
@@ -168,6 +177,8 @@
#gpio-cells = 2;
interrupts = 49;
interrupt-names = gpio_mux;
+   clocks = soc_clocks MMP2_CLK_GPIO;
+   resets = soc_clocks MMP2_CLK_GPIO;
interrupt-controller;
#interrupt-cells = 1;
ranges;
@@ -201,6 +212,8 @@
compatible = mrvl,mmp-twsi;
reg = 0xd4011000 0x1000;
interrupts = 7;
+   clocks = soc_clocks MMP2_CLK_TWSI0;
+   resets = soc_clocks MMP2_CLK_TWSI0;
#address-cells = 1;
#size-cells = 0;
mrvl,i2c-fast-mode;
@@ -211,6 +224,8 @@
compatible = mrvl,mmp-twsi;
reg = 0xd4025000 0x1000;
interrupts = 58;
+   clocks = soc_clocks MMP2_CLK_TWSI1;
+   resets = soc_clocks MMP2_CLK_TWSI1;
status = disabled;
};
 
@@ -220,8 +235,20 @@
interrupts = 1 0;
interrupt-names = rtc 1Hz, rtc alarm;
interrupt-parent = intcmux5;
+   clocks = soc_clocks MMP2_CLK_RTC;
+   resets = soc_clocks MMP2_CLK_RTC;
status = disabled;
};
};
+
+   soc_clocks: clocks{
+   compatible = marvell,mmp2-clock;
+   reg = 0xd405 0x1000,
+ 0xd4282800 0x400,
+ 0xd4015000 0x1000;
+   reg-names = mpmu, apmu, apbc;
+   #clock-cells = 1;
+   #reset-cells = 1;
+   };
};
 };
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index bfcbdef..b899e25 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -8,6 +8,7 @@
  */
 
 #include skeleton.dtsi
+#include dt-bindings/clock/marvell,pxa168

[PATCH V2 05/13] clk: mmp: add clock type mix

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

The clock type mix is a kind of clock combines div and mux.
This kind of clock can not allow to change div first then
mux or change mux first or div.
The reason is
1. Some clock has frequency change bit. Each time want to change
   the frequency, there are some operations based on this bit, and
   these operations are time-cost.
   Seperating div and mux change will make the process longer, and
   waste more time.
2. Seperting the div and mux may generate middle clock that the
   peripharals do not support. It may make the peripharals hang.

There are three kinds of this type of clock in all SOCes.
1. The clock has bit to trigger the frequency change.
2. Same as #1, but the operations for the bit is different
3. Do not have frequency change bit.

So this type of clock has implemented the callbacks
-determine_rate
-set_rate_and_parent
These callbacks can help to change the div and mux together.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/Makefile  |   2 +-
 drivers/clk/mmp/clk-mix.c | 513 ++
 drivers/clk/mmp/clk.h |  66 ++
 3 files changed, 580 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/clk-mix.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 392d780..8bfee860 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c
new file mode 100644
index 000..b79742c
--- /dev/null
+++ b/drivers/clk/mmp/clk-mix.c
@@ -0,0 +1,513 @@
+/*
+ * mmp mix(div and mux) clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie chao@marvell.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/clk-provider.h
+#include linux/slab.h
+#include linux/io.h
+#include linux/err.h
+
+#include clk.h
+
+/*
+ * The mix clock is a clock combined mux and div type clock.
+ * Because the div field and mux field need to be set at same
+ * time, we can not divide it into 2 types of clock
+ */
+
+#define to_clk_mix(hw) container_of(hw, struct mmp_clk_mix, hw)
+
+static unsigned int _get_maxdiv(struct mmp_clk_mix *mix)
+{
+   unsigned int div_mask = (1  mix-reg_info.width_div) - 1;
+   unsigned int maxdiv = 0;
+   struct clk_div_table *clkt;
+
+   if (mix-div_flags  CLK_DIVIDER_ONE_BASED)
+   return div_mask;
+   if (mix-div_flags  CLK_DIVIDER_POWER_OF_TWO)
+   return 1  div_mask;
+   if (mix-div_table) {
+   for (clkt = mix-div_table; clkt-div; clkt++)
+   if (clkt-div  maxdiv)
+   maxdiv = clkt-div;
+   return maxdiv;
+   }
+   return div_mask + 1;
+}
+
+static unsigned int _get_div(struct mmp_clk_mix *mix, unsigned int val)
+{
+   struct clk_div_table *clkt;
+
+   if (mix-div_flags  CLK_DIVIDER_ONE_BASED)
+   return val;
+   if (mix-div_flags  CLK_DIVIDER_POWER_OF_TWO)
+   return 1  val;
+   if (mix-div_table) {
+   for (clkt = mix-div_table; clkt-div; clkt++)
+   if (clkt-val == val)
+   return clkt-div;
+   if (clkt-div == 0)
+   return 0;
+   }
+   return val + 1;
+}
+
+static unsigned int _get_mux(struct mmp_clk_mix *mix, unsigned int val)
+{
+   int num_parents = __clk_get_num_parents(mix-hw.clk);
+   int i;
+
+   if (mix-mux_flags  CLK_MUX_INDEX_BIT)
+   return ffs(val) - 1;
+   if (mix-mux_flags  CLK_MUX_INDEX_ONE)
+   return val - 1;
+   if (mix-mux_table) {
+   for (i = 0; i  num_parents; i++)
+   if (mix-mux_table[i] == val)
+   return i;
+   if (i == num_parents)
+   return 0;
+   }
+
+   return val;
+}
+static unsigned int _get_div_val(struct mmp_clk_mix *mix, unsigned int div)
+{
+   struct clk_div_table *clkt;
+
+   if (mix-div_flags  CLK_DIVIDER_ONE_BASED)
+   return div;
+   if (mix-div_flags  CLK_DIVIDER_POWER_OF_TWO)
+   return __ffs(div);
+   if (mix-div_table) {
+   for (clkt = mix-div_table; clkt-div; clkt++)
+   if (clkt-div == div)
+   return clkt-val;
+   if (clkt-div == 0)
+   return 0;
+   }
+
+   return div - 1;
+}
+
+static unsigned int _get_mux_val(struct mmp_clk_mix *mix, unsigned int mux)
+{
+   if (mix-mux_table

[PATCH V2 10/13] clk: mmp: add pxa910 DT support for clock driver

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

It adds the DT support for pxa910 clock subsystem.

Signed-off-by: Chao Xie chao@marvell.com
---
 .../devicetree/bindings/clock/marvell,pxa910.txt   |  21 ++
 drivers/clk/mmp/Makefile   |   2 +-
 drivers/clk/mmp/clk-of-pxa910.c| 301 +
 include/dt-bindings/clock/marvell,pxa910.h |  54 
 4 files changed, 377 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,pxa910.txt
 create mode 100644 drivers/clk/mmp/clk-of-pxa910.c
 create mode 100644 include/dt-bindings/clock/marvell,pxa910.h

diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa910.txt 
b/Documentation/devicetree/bindings/clock/marvell,pxa910.txt
new file mode 100644
index 000..d9f41f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell,pxa910.txt
@@ -0,0 +1,21 @@
+* Marvell PXA910 Clock Controller
+
+The PXA910 clock subsystem generates and supplies clock to various
+controllers within the PXA910 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - marvell,pxa910-clock - controller compatible with PXA910 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 4 places in SOC has clock control logic:
+  mpmu, apmu, apbc, apbcp. So four reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in dt-bindings/clock/marvell-pxa910.h.
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 733acc7..947cd74 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -6,7 +6,7 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o 
clk.o
 
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 
-obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
new file mode 100644
index 000..5e3c80d
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -0,0 +1,301 @@
+/*
+ * pxa910 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie xiechao.m...@gmail.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/spinlock.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/err.h
+#include linux/of_address.h
+
+#include dt-bindings/clock/marvell,pxa910.h
+
+#include clk.h
+#include reset.h
+
+#define APBC_RTC   0x28
+#define APBC_TWSI0 0x2c
+#define APBC_KPC   0x18
+#define APBC_UART0 0x0
+#define APBC_UART1 0x4
+#define APBC_GPIO  0x8
+#define APBC_PWM0  0xc
+#define APBC_PWM1  0x10
+#define APBC_PWM2  0x14
+#define APBC_PWM3  0x18
+#define APBC_SSP0  0x1c
+#define APBC_SSP1  0x20
+#define APBC_SSP2  0x4c
+#define APBCP_TWSI10x28
+#define APBCP_UART20x1c
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_CCIC0 0x50
+#define APMU_DFC   0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa910_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+   void __iomem *apbcp_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {PXA910_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
+   {PXA910_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
+   {PXA910_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 62400},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {PXA910_CLK_PLL1_2, pll1_2, pll1, 1, 2, 0},
+   {PXA910_CLK_PLL1_4, pll1_4, pll1_2, 1, 2, 0},
+   {PXA910_CLK_PLL1_8, pll1_8, pll1_4, 1, 2, 0},
+   {PXA910_CLK_PLL1_16, pll1_16, pll1_8, 1, 2, 0},
+   {PXA910_CLK_PLL1_6, pll1_6, pll1_2, 1, 3, 0},
+   {PXA910_CLK_PLL1_12, pll1_12, pll1_6, 1, 2, 0},
+   {PXA910_CLK_PLL1_24, pll1_24, pll1_12, 1, 2, 0},
+   {PXA910_CLK_PLL1_48, pll1_48, pll1_24, 1, 2, 0},
+   {PXA910_CLK_PLL1_96, pll1_96, pll1_48, 1, 2, 0},
+   {PXA910_CLK_PLL1_13, pll1_13, pll1, 1, 13, 0},
+   {PXA910_CLK_PLL1_13_1_5, pll1_13_1_5, pll1_13, 2, 3, 0},
+   {PXA910_CLK_PLL1_2_1_5, pll1_2_1_5, pll1_2, 2, 3, 0},
+   {PXA910_CLK_PLL1_3_16, pll1_3_16, pll1, 3, 16, 0},
+};
+
+static struct mmp_clk_factor_masks uart_factor_masks = {
+   .factor = 2,
+   .num_mask = 0x1fff,
+   .den_mask = 0x1fff,
+   .num_shift = 16

[PATCH V2 09/13] clk: mmp: add pxa168 DT support for clock driver

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

It adds the DT support for pxa168 clock subsystem.

Signed-off-by: Chao Xie chao@marvell.com
---
 .../devicetree/bindings/clock/marvell,pxa168.txt   |  21 ++
 drivers/clk/mmp/Makefile   |   2 +
 drivers/clk/mmp/clk-of-pxa168.c| 279 +
 include/dt-bindings/clock/marvell,pxa168.h |  57 +
 4 files changed, 359 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,pxa168.txt
 create mode 100644 drivers/clk/mmp/clk-of-pxa168.c
 create mode 100644 include/dt-bindings/clock/marvell,pxa168.h

diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa168.txt 
b/Documentation/devicetree/bindings/clock/marvell,pxa168.txt
new file mode 100644
index 000..c62eb1d
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell,pxa168.txt
@@ -0,0 +1,21 @@
+* Marvell PXA168 Clock Controller
+
+The PXA168 clock subsystem generates and supplies clock to various
+controllers within the PXA168 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - marvell,pxa168-clock - controller compatible with PXA168 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  mpmu, apmu, apbc. So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in dt-bindings/clock/marvell,pxa168.h.
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 2573d7c..733acc7 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -6,6 +6,8 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o 
clk.o
 
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o
+
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
 obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
new file mode 100644
index 000..5b1810d
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -0,0 +1,279 @@
+/*
+ * pxa168 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie xiechao.m...@gmail.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/spinlock.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/err.h
+#include linux/of_address.h
+
+#include dt-bindings/clock/marvell,pxa168.h
+
+#include clk.h
+#include reset.h
+
+#define APBC_RTC   0x28
+#define APBC_TWSI0 0x2c
+#define APBC_KPC   0x30
+#define APBC_UART0 0x0
+#define APBC_UART1 0x4
+#define APBC_GPIO  0x8
+#define APBC_PWM0  0xc
+#define APBC_PWM1  0x10
+#define APBC_PWM2  0x14
+#define APBC_PWM3  0x18
+#define APBC_SSP0  0x81c
+#define APBC_SSP1  0x820
+#define APBC_SSP2  0x84c
+#define APBC_SSP3  0x858
+#define APBC_SSP4  0x85c
+#define APBC_TWSI1 0x6c
+#define APBC_UART2 0x70
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_CCIC0 0x50
+#define APMU_DFC   0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa168_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {PXA168_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
+   {PXA168_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
+   {PXA168_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 62400},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {PXA168_CLK_PLL1_2, pll1_2, pll1, 1, 2, 0},
+   {PXA168_CLK_PLL1_4, pll1_4, pll1_2, 1, 2, 0},
+   {PXA168_CLK_PLL1_8, pll1_8, pll1_4, 1, 2, 0},
+   {PXA168_CLK_PLL1_16, pll1_16, pll1_8, 1, 2, 0},
+   {PXA168_CLK_PLL1_6, pll1_6, pll1_2, 1, 3, 0},
+   {PXA168_CLK_PLL1_12, pll1_12, pll1_6, 1, 2, 0},
+   {PXA168_CLK_PLL1_24, pll1_24, pll1_12, 1, 2, 0},
+   {PXA168_CLK_PLL1_48, pll1_48, pll1_24, 1, 2, 0},
+   {PXA168_CLK_PLL1_96, pll1_96, pll1_48, 1, 2, 0},
+   {PXA168_CLK_PLL1_13, pll1_13, pll1, 1, 13, 0},
+   {PXA168_CLK_PLL1_13_1_5, pll1_13_1_5, pll1_13, 2, 3, 0},
+   {PXA168_CLK_PLL1_2_1_5, pll1_2_1_5, pll1_2, 2, 3, 0},
+   {PXA168_CLK_PLL1_3_16, pll1_3_16, pll1, 3, 16, 0},
+};
+
+static struct mmp_clk_factor_masks uart_factor_masks = {
+   .factor = 2,
+   .num_mask = 0x1fff,
+   .den_mask = 0x1fff,
+   .num_shift = 16,
+   .den_shift = 0

[PATCH V2 11/13] clk: mmp: add mmp2 DT support for clock driver

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

It adds the DT support for mmp2 clock subsystem.

Signed-off-by: Chao Xie chao@marvell.com
---
 .../devicetree/bindings/clock/marvell,mmp2.txt |  21 ++
 drivers/clk/mmp/Makefile   |   1 +
 drivers/clk/mmp/clk-of-mmp2.c  | 334 +
 include/dt-bindings/clock/marvell,mmp2.h   |  74 +
 4 files changed, 430 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,mmp2.txt
 create mode 100644 drivers/clk/mmp/clk-of-mmp2.c
 create mode 100644 include/dt-bindings/clock/marvell,mmp2.h

diff --git a/Documentation/devicetree/bindings/clock/marvell,mmp2.txt 
b/Documentation/devicetree/bindings/clock/marvell,mmp2.txt
new file mode 100644
index 000..af376a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell,mmp2.txt
@@ -0,0 +1,21 @@
+* Marvell MMP2 Clock Controller
+
+The MMP2 clock subsystem generates and supplies clock to various
+controllers within the MMP2 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - marvell,mmp2-clock - controller compatible with MMP2 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  mpmu, apmu, apbc. So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in dt-bindings/clock/marvell-mmp2.h.
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 947cd74..3caaf7c 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -7,6 +7,7 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o 
clk.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 
 obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
+obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
new file mode 100644
index 000..2cbc2b4
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -0,0 +1,334 @@
+/*
+ * mmp2 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie xiechao.m...@gmail.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/spinlock.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/err.h
+#include linux/of_address.h
+
+#include dt-bindings/clock/marvell,mmp2.h
+
+#include clk.h
+#include reset.h
+
+#define APBC_RTC   0x0
+#define APBC_TWSI0 0x4
+#define APBC_TWSI1 0x8
+#define APBC_TWSI2 0xc
+#define APBC_TWSI3 0x10
+#define APBC_TWSI4 0x7c
+#define APBC_TWSI5 0x80
+#define APBC_KPC   0x18
+#define APBC_UART0 0x2c
+#define APBC_UART1 0x30
+#define APBC_UART2 0x34
+#define APBC_UART3 0x88
+#define APBC_GPIO  0x38
+#define APBC_PWM0  0x3c
+#define APBC_PWM1  0x40
+#define APBC_PWM2  0x44
+#define APBC_PWM3  0x48
+#define APBC_SSP0  0x50
+#define APBC_SSP1  0x54
+#define APBC_SSP2  0x58
+#define APBC_SSP3  0x5c
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_SDH2  0xe8
+#define APMU_SDH3  0xec
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_DISP1 0x110
+#define APMU_CCIC0 0x50
+#define APMU_CCIC1 0xf4
+#define MPMU_UART_PLL  0x14
+
+struct mmp2_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {MMP2_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
+   {MMP2_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
+   {MMP2_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 8},
+   {MMP2_CLK_PLL2, pll2, NULL, CLK_IS_ROOT, 96000},
+   {MMP2_CLK_USB_PLL, usb_pll, NULL, CLK_IS_ROOT, 48000},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {MMP2_CLK_PLL1_2, pll1_2, pll1, 1, 2, 0},
+   {MMP2_CLK_PLL1_4, pll1_4, pll1_2, 1, 2, 0},
+   {MMP2_CLK_PLL1_8, pll1_8, pll1_4, 1, 2, 0},
+   {MMP2_CLK_PLL1_16, pll1_16, pll1_8, 1, 2, 0},
+   {MMP2_CLK_PLL1_20, pll1_20, pll1_4, 1, 5, 0},
+   {MMP2_CLK_PLL1_3, pll1_3, pll1, 1, 3, 0},
+   {MMP2_CLK_PLL1_6, pll1_6, pll1_3, 1, 2, 0},
+   {MMP2_CLK_PLL1_12, pll1_12, pll1_6, 1, 2, 0},
+   {MMP2_CLK_PLL2_2, pll2_2, pll2, 1, 2, 0},
+   {MMP2_CLK_PLL2_4, pll2_4, pll2_2, 1, 2, 0},
+   {MMP2_CLK_PLL2_8, pll2_8, pll2_4, 1, 2, 0},
+   {MMP2_CLK_PLL2_16, pll2_16, pll2_8, 1, 2, 0

[PATCH V2 12/13] arm: mmp: Make all the dts file to be compiled by Makefile

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

Add items in arch/arm/boot/dt/Makefile to compile the dtb
for mach-mmp.
Change the dts and dtsi file to use #include instead of \include\

Signed-off-by: Chao Xie chao@marvell.com
---
 arch/arm/boot/dts/Makefile| 3 +++
 arch/arm/boot/dts/mmp2-brownstone.dts | 2 +-
 arch/arm/boot/dts/mmp2.dtsi   | 2 +-
 arch/arm/boot/dts/pxa168-aspenite.dts | 2 +-
 arch/arm/boot/dts/pxa168.dtsi | 2 +-
 arch/arm/boot/dts/pxa910-dkb.dts  | 2 +-
 arch/arm/boot/dts/pxa910.dtsi | 2 +-
 7 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b8c5cd3..f8f7613 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -159,6 +159,9 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
kirkwood-ts419-6282.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
+   pxa910-dkb.dtb \
+   mmp2-brownstone.dtb
 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
imx25-eukrea-mbimxsd25-baseboard.dtb \
diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts 
b/arch/arm/boot/dts/mmp2-brownstone.dts
index 7f70a39..350208c 100644
--- a/arch/arm/boot/dts/mmp2-brownstone.dts
+++ b/arch/arm/boot/dts/mmp2-brownstone.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ mmp2.dtsi
+#include mmp2.dtsi
 
 / {
model = Marvell MMP2 Brownstone Development Board;
diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 4e8b08c..e44f996 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ skeleton.dtsi
+#include skeleton.dtsi
 
 / {
aliases {
diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts 
b/arch/arm/boot/dts/pxa168-aspenite.dts
index e762fac..0a988b3 100644
--- a/arch/arm/boot/dts/pxa168-aspenite.dts
+++ b/arch/arm/boot/dts/pxa168-aspenite.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ pxa168.dtsi
+#include pxa168.dtsi
 
 / {
model = Marvell PXA168 Aspenite Development Board;
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index 975dad2..bfcbdef 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ skeleton.dtsi
+#include skeleton.dtsi
 
 / {
aliases {
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..c82f281 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ pxa910.dtsi
+#include pxa910.dtsi
 
 / {
model = Marvell PXA910 DKB Development Board;
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 0247c62..884c6e8 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ skeleton.dtsi
+#include skeleton.dtsi
 
 / {
aliases {
-- 
1.8.3.2

--
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 V2 08/13] clk: mmp: add reset support

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

Some clock control regsiter has bit to reset the cotroller.
So before enable the clock, we need deassert the reset pin.
Make use of reset controller framework to export reset interface
for device drivers, then device driver can control the reset action.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/Makefile |  2 +
 drivers/clk/mmp/reset.c  | 99 
 drivers/clk/mmp/reset.h  | 31 +++
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/clk/mmp/reset.c
 create mode 100644 drivers/clk/mmp/reset.h

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 32b5b90..2573d7c 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -4,6 +4,8 @@
 
 obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
+obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
 obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
diff --git a/drivers/clk/mmp/reset.c b/drivers/clk/mmp/reset.c
new file mode 100644
index 000..b54da1f
--- /dev/null
+++ b/drivers/clk/mmp/reset.c
@@ -0,0 +1,99 @@
+#include linux/slab.h
+#include linux/io.h
+#include linux/of.h
+#include linux/of_address.h
+#include linux/reset-controller.h
+
+#include reset.h
+
+#define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, 
rcdev)
+
+static int mmp_of_reset_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+   struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+   struct mmp_clk_reset_cell *cell;
+   int i;
+
+   if (WARN_ON(reset_spec-args_count != rcdev-of_reset_n_cells))
+   return -EINVAL;
+
+   for (i = 0; i  rcdev-nr_resets; i++) {
+   cell = unit-cells[i];
+   if (cell-clk_id == reset_spec-args[0])
+   break;
+   }
+
+   if (i == rcdev-nr_resets)
+   return -EINVAL;
+
+   return i;
+}
+
+static int mmp_clk_reset_assert(struct reset_controller_dev *rcdev,
+   unsigned long id)
+{
+   struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+   struct mmp_clk_reset_cell *cell;
+   unsigned long flags = 0;
+   u32 val;
+
+   cell = unit-cells[id];
+   if (cell-lock)
+   spin_lock_irqsave(cell-lock, flags);
+
+   val = readl(cell-reg);
+   val |= cell-bits;
+   writel(val, cell-reg);
+
+   if (cell-lock)
+   spin_unlock_irqrestore(cell-lock, flags);
+
+   return 0;
+}
+
+static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev,
+   unsigned long id)
+{
+   struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+   struct mmp_clk_reset_cell *cell;
+   unsigned long flags = 0;
+   u32 val;
+
+   cell = unit-cells[id];
+   if (cell-lock)
+   spin_lock_irqsave(cell-lock, flags);
+
+   val = readl(cell-reg);
+   val = ~cell-bits;
+   writel(val, cell-reg);
+
+   if (cell-lock)
+   spin_unlock_irqrestore(cell-lock, flags);
+
+   return 0;
+}
+
+static struct reset_control_ops mmp_clk_reset_ops = {
+   .assert = mmp_clk_reset_assert,
+   .deassert   = mmp_clk_reset_deassert,
+};
+
+void mmp_clk_reset_register(struct device_node *np,
+   struct mmp_clk_reset_cell *cells, int nr_resets)
+{
+   struct mmp_clk_reset_unit *unit;
+
+   unit = kzalloc(sizeof(*unit), GFP_KERNEL);
+   if (!unit)
+   return;
+
+   unit-cells = cells;
+   unit-rcdev.of_reset_n_cells = 1;
+   unit-rcdev.nr_resets = nr_resets;
+   unit-rcdev.ops = mmp_clk_reset_ops;
+   unit-rcdev.of_node = np;
+   unit-rcdev.of_xlate = mmp_of_reset_xlate;
+
+   reset_controller_register(unit-rcdev);
+}
diff --git a/drivers/clk/mmp/reset.h b/drivers/clk/mmp/reset.h
new file mode 100644
index 000..be8b1a7
--- /dev/null
+++ b/drivers/clk/mmp/reset.h
@@ -0,0 +1,31 @@
+#ifndef __MACH_MMP_CLK_RESET_H
+#define __MACH_MMP_CLK_RESET_H
+
+#include linux/reset-controller.h
+
+#define MMP_RESET_INVERT   1
+
+struct mmp_clk_reset_cell {
+   unsigned int clk_id;
+   void __iomem *reg;
+   u32 bits;
+   unsigned int flags;
+   spinlock_t *lock;
+};
+
+struct mmp_clk_reset_unit {
+   struct reset_controller_dev rcdev;
+   struct mmp_clk_reset_cell *cells;
+};
+
+#ifdef CONFIG_RESET_CONTROLLER
+void mmp_clk_reset_register(struct device_node *np,
+   struct mmp_clk_reset_cell *cells, int nr_resets);
+#else
+static inline void mmp_clk_reset_register(struct device_node *np,
+   struct mmp_clk_reset_cell *cells, int nr_resets)
+{
+}
+#endif
+
+#endif
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body

[PATCH V2 04/13] clk: mmp: move definiton of mmp_clk_frac to clk.h

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

Move the definition of structure of mmp_clk_frac to
clk.h.
So device tree support can use this structure.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c |  8 
 drivers/clk/mmp/clk.h  | 32 ++--
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 1876d2c..eeba52c 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -23,14 +23,6 @@
  */
 
 #define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
-struct mmp_clk_factor {
-   struct clk_hw   hw;
-   void __iomem*base;
-   struct mmp_clk_factor_masks *masks;
-   struct mmp_clk_factor_tbl   *ftbl;
-   unsigned intftbl_cnt;
-   spinlock_t *lock;
-};
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index b71b717..d267639 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -7,12 +7,14 @@
 #define APBC_NO_BUS_CTRL   BIT(0)
 #define APBC_POWER_CTRLBIT(1)
 
+
+/* Clock type factor */
 struct mmp_clk_factor_masks {
-   unsigned intfactor;
-   unsigned intnum_mask;
-   unsigned intden_mask;
-   unsigned intnum_shift;
-   unsigned intden_shift;
+   unsigned int factor;
+   unsigned int num_mask;
+   unsigned int den_mask;
+   unsigned int num_shift;
+   unsigned int den_shift;
 };
 
 struct mmp_clk_factor_tbl {
@@ -20,6 +22,21 @@ struct mmp_clk_factor_tbl {
unsigned int den;
 };
 
+struct mmp_clk_factor {
+   struct clk_hw hw;
+   void __iomem *base;
+   struct mmp_clk_factor_masks *masks;
+   struct mmp_clk_factor_tbl *ftbl;
+   unsigned int ftbl_cnt;
+   spinlock_t *lock;
+};
+
+extern struct clk *mmp_clk_register_factor(const char *name,
+   const char *parent_name, unsigned long flags,
+   void __iomem *base, struct mmp_clk_factor_masks *masks,
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t *lock);
+
 extern struct clk *mmp_clk_register_pll2(const char *name,
const char *parent_name, unsigned long flags);
 extern struct clk *mmp_clk_register_apbc(const char *name,
@@ -28,9 +45,4 @@ extern struct clk *mmp_clk_register_apbc(const char *name,
 extern struct clk *mmp_clk_register_apmu(const char *name,
const char *parent_name, void __iomem *base, u32 enable_mask,
spinlock_t *lock);
-extern struct clk *mmp_clk_register_factor(const char *name,
-   const char *parent_name, unsigned long flags,
-   void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
-   spinlock_t *lock);
 #endif
-- 
1.8.3.2

--
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 V2 06/13] clk: mmp: add mmp private gate clock

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

Some SOCes have this kind of the gate clock
1. There are some bits to control the gate not only one bit.
2. It is not always that 1 is to enable while 0 is to disable
   when write register.

So we have to define the mask, enable_val, disable_val for
this kind of gate clock.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/Makefile   |   2 +-
 drivers/clk/mmp/clk-gate.c | 133 +
 drivers/clk/mmp/clk.h  |  21 +++
 3 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/clk-gate.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 8bfee860..2855f7b 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
new file mode 100644
index 000..adbd9d6
--- /dev/null
+++ b/drivers/clk/mmp/clk-gate.c
@@ -0,0 +1,133 @@
+/*
+ * mmp gate clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie chao@marvell.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/clk-provider.h
+#include linux/slab.h
+#include linux/io.h
+#include linux/err.h
+#include linux/delay.h
+
+#include clk.h
+
+/*
+ * Some clocks will have mutiple bits to enable the clocks, and
+ * the bits to disable the clock is not same as enabling bits.
+ */
+
+#define to_clk_mmp_gate(hw)container_of(hw, struct mmp_clk_gate, hw)
+
+static int mmp_clk_gate_enable(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   struct clk *clk = hw-clk;
+   unsigned long flags = 0;
+   unsigned long rate;
+   u32 tmp;
+
+   if (gate-lock)
+   spin_lock_irqsave(gate-lock, flags);
+
+   tmp = readl(gate-reg);
+   tmp = ~gate-mask;
+   tmp |= gate-val_enable;
+   writel(tmp, gate-reg);
+
+   if (gate-lock)
+   spin_unlock_irqrestore(gate-lock, flags);
+
+   if (gate-flags  MMP_CLK_GATE_NEED_DELAY) {
+   rate = __clk_get_rate(clk);
+   /* Need delay 2 cycles. */
+   udelay(200/rate);
+   }
+
+   return 0;
+}
+
+static void mmp_clk_gate_disable(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   unsigned long flags = 0;
+   u32 tmp;
+
+   if (gate-lock)
+   spin_lock_irqsave(gate-lock, flags);
+
+   tmp = readl(gate-reg);
+   tmp = ~gate-mask;
+   tmp |= gate-val_disable;
+   writel(tmp, gate-reg);
+
+   if (gate-lock)
+   spin_unlock_irqrestore(gate-lock, flags);
+}
+
+static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   unsigned long flags = 0;
+   u32 tmp;
+
+   if (gate-lock)
+   spin_lock_irqsave(gate-lock, flags);
+
+   tmp = readl(gate-reg);
+
+   if (gate-lock)
+   spin_unlock_irqrestore(gate-lock, flags);
+
+   return (tmp  gate-mask) == gate-val_enable;
+}
+
+const struct clk_ops mmp_clk_gate_ops = {
+   .enable = mmp_clk_gate_enable,
+   .disable = mmp_clk_gate_disable,
+   .is_enabled = mmp_clk_gate_is_enabled,
+};
+
+struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
+   const char *parent_name, unsigned long flags,
+   void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
+   unsigned int gate_flags, spinlock_t *lock)
+{
+   struct mmp_clk_gate *gate;
+   struct clk *clk;
+   struct clk_init_data init;
+
+   /* allocate the gate */
+   gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+   if (!gate) {
+   pr_err(%s:%s could not allocate gate clk\n, __func__, name);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   init.name = name;
+   init.ops = mmp_clk_gate_ops;
+   init.flags = flags | CLK_IS_BASIC;
+   init.parent_names = (parent_name ? parent_name : NULL);
+   init.num_parents = (parent_name ? 1 : 0);
+
+   /* struct clk_gate assignments */
+   gate-reg = reg;
+   gate-mask = mask;
+   gate-val_enable = val_enable;
+   gate-val_disable = val_disable;
+   gate-flags = gate_flags;
+   gate-lock = lock;
+   gate-hw.init = init;
+
+   clk = clk_register(dev, gate-hw);
+
+   if (IS_ERR(clk))
+   kfree(gate);
+
+   return clk;
+}
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 26b2469..2337106 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp

[PATCH V2 01/13] clk: mmp: add prefix mmp for structures defined for clk-frac

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

The structures defined for clk-frac will be used out side
of clk-frac.c.
To avoid conflicts, add prefix mmp for these structures'
name.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c   | 23 ---
 drivers/clk/mmp/clk-mmp2.c   |  4 ++--
 drivers/clk/mmp/clk-pxa168.c |  4 ++--
 drivers/clk/mmp/clk-pxa910.c |  4 ++--
 drivers/clk/mmp/clk.h|  8 
 5 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 23a56f5..3fbc9ca 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -22,19 +22,19 @@
  * numerator/denominator = Fin / (Fout * factor)
  */
 
-#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw)
-struct clk_factor {
+#define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
+struct mmp_clk_factor {
struct clk_hw   hw;
void __iomem*base;
-   struct clk_factor_masks *masks;
-   struct clk_factor_tbl   *ftbl;
+   struct mmp_clk_factor_masks *masks;
+   struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
unsigned long rate = 0, prev_rate;
int i;
 
@@ -58,8 +58,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned 
long drate,
 static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
-   struct clk_factor_masks *masks = factor-masks;
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor-masks;
unsigned int val, num, den;
 
val = readl_relaxed(factor-base);
@@ -81,8 +81,8 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
 static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
-   struct clk_factor_masks *masks = factor-masks;
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor-masks;
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
@@ -118,10 +118,11 @@ static struct clk_ops clk_factor_ops = {
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
unsigned long flags, void __iomem *base,
-   struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl,
+   struct mmp_clk_factor_masks *masks,
+   struct mmp_clk_factor_tbl *ftbl,
unsigned int ftbl_cnt)
 {
-   struct clk_factor *factor;
+   struct mmp_clk_factor *factor;
struct clk_init_data init;
struct clk *clk;
 
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index b2721ca..7083f12 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -54,7 +54,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 14634, .den = 2165},/*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
{.num = 9679, .den = 5728}, /*58.9824MHZ */
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 014396b..75266ac 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -47,7 +47,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 8125, .den = 1536}, /*14.745MHZ */
 };
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index 9efc6a4..f817999 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -45,7 +45,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff

[PATCH V2 03/13] clk: mmp: add init callback for clk-frac

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

For the clk-frac, we need to make sure that the initial
clock rate is one item of the table.
If it is not, we use the first item in the table by default.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index e29d006..1876d2c 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -118,10 +118,50 @@ static int clk_factor_set_rate(struct clk_hw *hw, 
unsigned long drate,
return 0;
 }
 
+void clk_factor_init(struct clk_hw *hw)
+{
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor-masks;
+   u32 val, num, den;
+   int i;
+   unsigned long flags = 0;
+
+   if (factor-lock)
+   spin_lock_irqsave(factor-lock, flags);
+
+   val = readl(factor-base);
+
+   /* calculate numerator */
+   num = (val  masks-num_shift)  masks-num_mask;
+
+   /* calculate denominator */
+   den = (val  masks-den_shift)  masks-den_mask;
+
+   for (i = 0; i  factor-ftbl_cnt; i++)
+   if (den == factor-ftbl[i].den  num == factor-ftbl[i].num)
+   break;
+
+   if (i = factor-ftbl_cnt) {
+   val = ~(masks-num_mask  masks-num_shift);
+   val |= (factor-ftbl[0].num  masks-num_mask) 
+   masks-num_shift;
+
+   val = ~(masks-den_mask  masks-den_shift);
+   val |= (factor-ftbl[0].den  masks-den_mask) 
+   masks-den_shift;
+
+   writel(val, factor-base);
+   }
+
+   if (factor-lock)
+   spin_unlock_irqrestore(factor-lock, flags);
+}
+
 static struct clk_ops clk_factor_ops = {
.recalc_rate = clk_factor_recalc_rate,
.round_rate = clk_factor_round_rate,
.set_rate = clk_factor_set_rate,
+   .init = clk_factor_init,
 };
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
-- 
1.8.3.2

--
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 V2 07/13] clk: mmp: add basic support functions for DT support

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

In order to support DT for mmp SOC clocks, it defines
some basic APIs which are shared by all mmp SOC clock
units.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/Makefile |   2 +-
 drivers/clk/mmp/clk.c| 192 +++
 drivers/clk/mmp/clk.h| 106 +-
 3 files changed, 298 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/mmp/clk.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 2855f7b..32b5b90 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
new file mode 100644
index 000..cf038ef
--- /dev/null
+++ b/drivers/clk/mmp/clk.c
@@ -0,0 +1,192 @@
+#include linux/io.h
+#include linux/clk.h
+#include linux/clk-provider.h
+#include linux/clkdev.h
+#include linux/of.h
+#include linux/of_address.h
+
+#include clk.h
+
+void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
+   int nr_clks)
+{
+   static struct clk **clk_table;
+
+   clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
+   if (!clk_table)
+   return;
+
+   unit-clk_table = clk_table;
+   unit-nr_clks = nr_clks;
+   unit-clk_data.clks = clk_table;
+   unit-clk_data.clk_num = nr_clks;
+   of_clk_add_provider(np, of_clk_src_onecell_get, unit-clk_data);
+}
+
+void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_fixed_rate_clk *clks,
+   int size)
+{
+   int i;
+   struct clk *clk;
+
+   for (i = 0; i  size; i++) {
+   clk = clk_register_fixed_rate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   clks[i].fixed_rate);
+   if (IS_ERR(clk)) {
+   pr_err(%s: failed to register clock %s\n,
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit-clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_fixed_factor_clk *clks,
+   int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i  size; i++) {
+   clk = clk_register_fixed_factor(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags, clks[i].mult,
+   clks[i].div);
+   if (IS_ERR(clk)) {
+   pr_err(%s: failed to register clock %s\n,
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit-clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_general_gate_clk *clks,
+   void __iomem *base, int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i  size; i++) {
+   clk = clk_register_gate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   base + clks[i].offset,
+   clks[i].bit_idx,
+   clks[i].gate_flags,
+   clks[i].lock);
+
+   if (IS_ERR(clk)) {
+   pr_err(%s: failed to register clock %s\n,
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit-clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_gate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_gate_clk *clks,
+   void __iomem *base, int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i  size; i++) {
+   clk = mmp_clk_register_gate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   base + clks[i].offset,
+   clks[i].mask,
+   clks[i].val_enable

[PATCH V2 02/13] clk: mmp: add spin lock for clk-frac

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c   | 11 ++-
 drivers/clk/mmp/clk-mmp2.c   |  2 +-
 drivers/clk/mmp/clk-pxa168.c |  2 +-
 drivers/clk/mmp/clk-pxa910.c |  2 +-
 drivers/clk/mmp/clk.h|  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 3fbc9ca..e29d006 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -29,6 +29,7 @@ struct mmp_clk_factor {
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
+   spinlock_t *lock;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
+   unsigned long flags = 0;
 
for (i = 0; i  factor-ftbl_cnt; i++) {
prev_rate = rate;
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
if (i  0)
i--;
 
+   if (factor-lock)
+   spin_lock_irqsave(factor-lock, flags);
+
val = readl_relaxed(factor-base);
 
val = ~(masks-num_mask  masks-num_shift);
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
 
writel_relaxed(val, factor-base);
 
+   if (factor-lock)
+   spin_unlock_irqrestore(factor-lock, flags);
+
return 0;
 }
 
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
unsigned long flags, void __iomem *base,
struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl,
-   unsigned int ftbl_cnt)
+   unsigned int ftbl_cnt, spinlock_t *lock)
 {
struct mmp_clk_factor *factor;
struct clk_init_data init;
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
factor-ftbl = ftbl;
factor-ftbl_cnt = ftbl_cnt;
factor-hw.init = init;
+   factor-lock = lock;
 
init.name = name;
init.ops = clk_factor_ops;
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 7083f12..5c90a42 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 75266ac..93e967c 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index f817999..993abcd 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll =  mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 3fe92be..b71b717 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name,
 extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt);
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t

[PATCH V2 00/13] clk: mmp: clock device tree support

2014-10-30 Thread Chao Xie
From: Chao Xie chao@marvell.com

The patch set focuses at support device tree for clock.

The first part of the patches
  clk: mmp: add prefix mmp for structures defined for clk-frac
  clk: mmp: add spin lock for clk-frac
  clk: mmp: add init callback for clk-frac
  clk: mmp: move definiton of mmp_clk_frac to clk.h It enhances the clk-frac.

The second part of the patches
  clk: mmp: add clock type mix
  clk: mmp: add mmp private gate clock

The third part of the patches
  clk: mmp: add basic support functions for DT support
  clk: mmp: add reset support
  clk: mmp: add pxa168 DT support for clock driver
  clk: mmp: add pxa910 DT support for clock driver
  clk: mmp: add mmp2 DT support for clock driver
It add the device tree support for pxa168, pxa910 and mmp2.

V1 - V2:
  Add reset support for the clocks that have reset bit.

Chao Xie (13):
  clk: mmp: add prefix mmp for structures defined for clk-frac
  clk: mmp: add spin lock for clk-frac
  clk: mmp: add init callback for clk-frac
  clk: mmp: move definiton of mmp_clk_frac to clk.h
  clk: mmp: add clock type mix
  clk: mmp: add mmp private gate clock
  clk: mmp: add basic support functions for DT support
  clk: mmp: add reset support
  clk: mmp: add pxa168 DT support for clock driver
  clk: mmp: add pxa910 DT support for clock driver
  clk: mmp: add mmp2 DT support for clock driver
  arm: mmp: Make all the dts file to be compiled by Makefile
  arm: mmp: Make use of the DT supported clock

 .../devicetree/bindings/clock/marvell,mmp2.txt |  21 +
 .../devicetree/bindings/clock/marvell,pxa168.txt   |  21 +
 .../devicetree/bindings/clock/marvell,pxa910.txt   |  21 +
 arch/arm/boot/dts/Makefile |   3 +
 arch/arm/boot/dts/mmp2-brownstone.dts  |   2 +-
 arch/arm/boot/dts/mmp2.dtsi|  29 +-
 arch/arm/boot/dts/pxa168-aspenite.dts  |   2 +-
 arch/arm/boot/dts/pxa168.dtsi  |  27 +-
 arch/arm/boot/dts/pxa910-dkb.dts   |   2 +-
 arch/arm/boot/dts/pxa910.dtsi  |  28 +-
 arch/arm/mach-mmp/Kconfig  |  12 +-
 arch/arm/mach-mmp/mmp-dt.c |  57 +--
 arch/arm/mach-mmp/mmp2-dt.c|  26 +-
 drivers/clk/mmp/Makefile   |   7 +-
 drivers/clk/mmp/clk-frac.c |  74 ++-
 drivers/clk/mmp/clk-gate.c | 133 ++
 drivers/clk/mmp/clk-mix.c  | 513 +
 drivers/clk/mmp/clk-mmp2.c |   6 +-
 drivers/clk/mmp/clk-of-mmp2.c  | 334 ++
 drivers/clk/mmp/clk-of-pxa168.c| 279 +++
 drivers/clk/mmp/clk-of-pxa910.c| 301 
 drivers/clk/mmp/clk-pxa168.c   |   6 +-
 drivers/clk/mmp/clk-pxa910.c   |   6 +-
 drivers/clk/mmp/clk.c  | 192 
 drivers/clk/mmp/clk.h  | 226 -
 drivers/clk/mmp/reset.c|  99 
 drivers/clk/mmp/reset.h|  31 ++
 include/dt-bindings/clock/marvell,mmp2.h   |  74 +++
 include/dt-bindings/clock/marvell,pxa168.h |  57 +++
 include/dt-bindings/clock/marvell,pxa910.h |  54 +++
 30 files changed, 2538 insertions(+), 105 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,mmp2.txt
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,pxa168.txt
 create mode 100644 Documentation/devicetree/bindings/clock/marvell,pxa910.txt
 create mode 100644 drivers/clk/mmp/clk-gate.c
 create mode 100644 drivers/clk/mmp/clk-mix.c
 create mode 100644 drivers/clk/mmp/clk-of-mmp2.c
 create mode 100644 drivers/clk/mmp/clk-of-pxa168.c
 create mode 100644 drivers/clk/mmp/clk-of-pxa910.c
 create mode 100644 drivers/clk/mmp/clk.c
 create mode 100644 drivers/clk/mmp/reset.c
 create mode 100644 drivers/clk/mmp/reset.h
 create mode 100644 include/dt-bindings/clock/marvell,mmp2.h
 create mode 100644 include/dt-bindings/clock/marvell,pxa168.h
 create mode 100644 include/dt-bindings/clock/marvell,pxa910.h

-- 
1.8.3.2

--
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:Re: [PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-09-09 Thread Chao Xie

At 2014-09-04 02:04:24, "Mike Turquette"  wrote:
>Quoting Chao Xie (2014-08-25 21:38:14)
>> From: Chao Xie 
>> 
>> The register used by clk-frac may be shared with
>> other clocks.
>> So it needs to use spin lock to protect the register
>> access.
>> 
>> Signed-off-by: Chao Xie 
>
>This patch will break against the latest clk-next due to api changes.
>You can see more here[0] and use this script to update your code if you
>like[1].
>
>Basically the calls to clk_set_rate need to be changed to
>clk_provider_set_rate.

>
I see the patch set [0] is V10 now, and it is not merged to clk-next yet.
So should i wait for the patch set to be merged, then send out the updated 
patches?

>[0] 
>http://lkml.kernel.org/r/<1409758148-20104-1-git-send-email-tomeu.viz...@collabora.com>
>[1] 
>http://cgit.collabora.com/git/user/tomeu/linux.git/commit/?h=clk-refactoring-9=ea48c0d655346cce26329523cf24574f9ea8feee
>
>Regards,
>Mike
N嫥叉靣笡y氊b瞂千v豝�)藓{.n�+壏{睉赙zXФ洝塄}财爖�:+v墾�珣赙zZ+€�+zf"穐殘啳嗃iz�畐ア�?櫒璀�&�)撷f旟^j谦y呩@A玜囤
0鹅h�鍜i

Re:Re: [PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-09-09 Thread Chao Xie

At 2014-09-04 02:04:24, Mike Turquette mturque...@linaro.org wrote:
Quoting Chao Xie (2014-08-25 21:38:14)
 From: Chao Xie chao@marvell.com
 
 The register used by clk-frac may be shared with
 other clocks.
 So it needs to use spin lock to protect the register
 access.
 
 Signed-off-by: Chao Xie chao@marvell.com

This patch will break against the latest clk-next due to api changes.
You can see more here[0] and use this script to update your code if you
like[1].

Basically the calls to clk_set_rate need to be changed to
clk_provider_set_rate.


I see the patch set [0] is V10 now, and it is not merged to clk-next yet.
So should i wait for the patch set to be merged, then send out the updated 
patches?

[0] 
http://lkml.kernel.org/r/1409758148-20104-1-git-send-email-tomeu.viz...@collabora.com
[1] 
http://cgit.collabora.com/git/user/tomeu/linux.git/commit/?h=clk-refactoring-9id=ea48c0d655346cce26329523cf24574f9ea8feee

Regards,
Mike
N嫥叉靣笡y氊b瞂千v豝�)藓{.n�+壏{睉赙zXФ洝塄}财爖�j:+v墾�珣赙zZ+€�+zf"穐殘啳嗃iz�畐ア�?櫒璀��)撷f旟^j谦y呩@A玜囤
0鹅h�鍜i

Re:Re: [PATCH 06/12] clk: mmp: add mmp private gate clock

2014-09-03 Thread Chao Xie


At 2014-09-04 01:55:37, "Mike Turquette"  wrote:
>Quoting Chao Xie (2014-08-25 21:38:18)
>> From: Chao Xie 
>> 
>> Some SOCes have this kind of the gate clock
>> 1. There are some bits to control the gate not only one bit.
>> 2. Some clocks has operations of "out of reset" and "enable".
>>To enable clock, we need do "out of reset" and "enable".
>>To disable clock, we may not need "set to reset". It depends
>>on the SOCes' design.
>
>Are there any other IP blocks affected by the "out of reset" and "set to
>reset" states? I wonder if you might benefit from the reset controller
>framework?  For example see,
>
>drivers/clk/qcom/gcc-apq8084.c
>
>

>
Thanks to point it out.
To use the reset framework, there are some problem.
1. the reset bit is combined with the clocks disable/enable bits in same 
register. Seperating setting them means spinlock
protection and 2 operations for read-update the bits.


except that, i think reset framework can bring some benefits.


Even without the reset bit, we still need the gate clocks.
The enable/disable is not a bit operation, and it is bits operation for some 
devices.
In fact i want to use it to replace the old clk-apbc and clk-apmu clocks. 

>> +static int mmp_clk_gate_enable(struct clk_hw *hw)
>> +{
>> +   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
>> +   struct clk *clk = hw->clk;
>> +   unsigned long flags = 0;
>> +   unsigned long rate;
>> +   u32 tmp;
>> +
>> +   if (gate->lock)
>> +   spin_lock_irqsave(gate->lock, flags);
>> +
>> +   tmp = readl(gate->reg);
>> +   tmp &= ~gate->mask;
>> +   tmp |= gate->val_enable;
>> +   writel(tmp, gate->reg);
>> +
>> +   if (gate->lock)
>> +   spin_unlock_irqrestore(gate->lock, flags);
>> +
>> +   if (gate->flags & MMP_CLK_GATE_NEED_DELAY) {
>> +   rate = __clk_get_rate(clk);
>> +   /* Need delay 2 cycles. */
>> +   udelay(200/rate);
>
>How long are these delays? Long enough to warrant using clk_prepare
>instead of clk_enable? Are these clocks enabled from interrupt context?

>
For power optimization, some clocks need to be enabled/disable in interrupt 
context.
The worst delay is rate=32KHZ, so the delay is 62.5us.

>Regards,
>Mike


N嫥叉靣笡y氊b瞂千v豝�)藓{.n�+壏{睉赙zXФ洝塄}财爖�:+v墾�珣赙zZ+€�+zf"穐殘啳嗃iz�畐ア�?櫒璀�&�)撷f旟^j谦y呩@A玜囤
0鹅h�鍜i

Re:Re: [PATCH 06/12] clk: mmp: add mmp private gate clock

2014-09-03 Thread Chao Xie


At 2014-09-04 01:55:37, Mike Turquette mturque...@linaro.org wrote:
Quoting Chao Xie (2014-08-25 21:38:18)
 From: Chao Xie chao@marvell.com
 
 Some SOCes have this kind of the gate clock
 1. There are some bits to control the gate not only one bit.
 2. Some clocks has operations of out of reset and enable.
To enable clock, we need do out of reset and enable.
To disable clock, we may not need set to reset. It depends
on the SOCes' design.

Are there any other IP blocks affected by the out of reset and set to
reset states? I wonder if you might benefit from the reset controller
framework?  For example see,

drivers/clk/qcom/gcc-apq8084.c

snip


Thanks to point it out.
To use the reset framework, there are some problem.
1. the reset bit is combined with the clocks disable/enable bits in same 
register. Seperating setting them means spinlock
protection and 2 operations for read-update the bits.


except that, i think reset framework can bring some benefits.


Even without the reset bit, we still need the gate clocks.
The enable/disable is not a bit operation, and it is bits operation for some 
devices.
In fact i want to use it to replace the old clk-apbc and clk-apmu clocks. 

 +static int mmp_clk_gate_enable(struct clk_hw *hw)
 +{
 +   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
 +   struct clk *clk = hw-clk;
 +   unsigned long flags = 0;
 +   unsigned long rate;
 +   u32 tmp;
 +
 +   if (gate-lock)
 +   spin_lock_irqsave(gate-lock, flags);
 +
 +   tmp = readl(gate-reg);
 +   tmp = ~gate-mask;
 +   tmp |= gate-val_enable;
 +   writel(tmp, gate-reg);
 +
 +   if (gate-lock)
 +   spin_unlock_irqrestore(gate-lock, flags);
 +
 +   if (gate-flags  MMP_CLK_GATE_NEED_DELAY) {
 +   rate = __clk_get_rate(clk);
 +   /* Need delay 2 cycles. */
 +   udelay(200/rate);

How long are these delays? Long enough to warrant using clk_prepare
instead of clk_enable? Are these clocks enabled from interrupt context?


For power optimization, some clocks need to be enabled/disable in interrupt 
context.
The worst delay is rate=32KHZ, so the delay is 62.5us.

Regards,
Mike


N嫥叉靣笡y氊b瞂千v豝�)藓{.n�+壏{睉赙zXФ洝塄}财爖�j:+v墾�珣赙zZ+€�+zf"穐殘啳嗃iz�畐ア�?櫒璀��)撷f旟^j谦y呩@A玜囤
0鹅h�鍜i

[PATCH 05/12] clk: mmp: add clock type mix

2014-08-25 Thread Chao Xie
From: Chao Xie 

The clock type mix is a kind of clock combines "div" and "mux".
This kind of clock can not allow to change div first then
mux or change mux first or div.
The reason is
1. Some clock has frequency change bit. Each time want to change
   the frequency, there are some operations based on this bit, and
   these operations are time-cost.
   Seperating div and mux change will make the process longer, and
   waste more time.
2. Seperting the div and mux may generate middle clock that the
   peripharals do not support. It may make the peripharals hang.

There are three kinds of this type of clock in all SOCes.
1. The clock has bit to trigger the frequency change.
2. Same as #1, but the operations for the bit is different
3. Do not have frequency change bit.

So this type of clock has implemented the callbacks
->determine_rate
->set_rate_and_parent
These callbacks can help to change the div and mux together.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/Makefile  |   2 +-
 drivers/clk/mmp/clk-mix.c | 513 ++
 drivers/clk/mmp/clk.h |  66 ++
 3 files changed, 580 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/clk-mix.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 392d780..8bfee860 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c
new file mode 100644
index 000..b79742c
--- /dev/null
+++ b/drivers/clk/mmp/clk-mix.c
@@ -0,0 +1,513 @@
+/*
+ * mmp mix(div and mux) clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+
+/*
+ * The mix clock is a clock combined mux and div type clock.
+ * Because the div field and mux field need to be set at same
+ * time, we can not divide it into 2 types of clock
+ */
+
+#define to_clk_mix(hw) container_of(hw, struct mmp_clk_mix, hw)
+
+static unsigned int _get_maxdiv(struct mmp_clk_mix *mix)
+{
+   unsigned int div_mask = (1 << mix->reg_info.width_div) - 1;
+   unsigned int maxdiv = 0;
+   struct clk_div_table *clkt;
+
+   if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+   return div_mask;
+   if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+   return 1 << div_mask;
+   if (mix->div_table) {
+   for (clkt = mix->div_table; clkt->div; clkt++)
+   if (clkt->div > maxdiv)
+   maxdiv = clkt->div;
+   return maxdiv;
+   }
+   return div_mask + 1;
+}
+
+static unsigned int _get_div(struct mmp_clk_mix *mix, unsigned int val)
+{
+   struct clk_div_table *clkt;
+
+   if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+   return val;
+   if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+   return 1 << val;
+   if (mix->div_table) {
+   for (clkt = mix->div_table; clkt->div; clkt++)
+   if (clkt->val == val)
+   return clkt->div;
+   if (clkt->div == 0)
+   return 0;
+   }
+   return val + 1;
+}
+
+static unsigned int _get_mux(struct mmp_clk_mix *mix, unsigned int val)
+{
+   int num_parents = __clk_get_num_parents(mix->hw.clk);
+   int i;
+
+   if (mix->mux_flags & CLK_MUX_INDEX_BIT)
+   return ffs(val) - 1;
+   if (mix->mux_flags & CLK_MUX_INDEX_ONE)
+   return val - 1;
+   if (mix->mux_table) {
+   for (i = 0; i < num_parents; i++)
+   if (mix->mux_table[i] == val)
+   return i;
+   if (i == num_parents)
+   return 0;
+   }
+
+   return val;
+}
+static unsigned int _get_div_val(struct mmp_clk_mix *mix, unsigned int div)
+{
+   struct clk_div_table *clkt;
+
+   if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+   return div;
+   if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+   return __ffs(div);
+   if (mix->div_table) {
+   for (clkt = mix->div_table; clkt->div; clkt++)
+   if (clkt->div == div)
+   return clkt->val;
+   if (clkt->div == 0)
+   return 0;
+   }
+
+   

[PATCH 00/12] clk: mmp: clock device tree support

2014-08-25 Thread Chao Xie
From: Chao Xie 

The patch set focuses at support device tree for clock.

The first part of the patches
  clk: mmp: add prefix "mmp" for structures defined for clk-frac
  clk: mmp: add spin lock for clk-frac
  clk: mmp: add init callback for clk-frac
  clk: mmp: move definiton of mmp_clk_frac to clk.h It enhances the clk-frac.

The second part of the patches
  clk: mmp: add clock type mix
  clk: mmp: add mmp private gate clock

The third part of the patches
  clk: mmp: add basic support functions for DT support
  clk: mmp: add pxa168 DT support for clock driver
  clk: mmp: add pxa910 DT support for clock driver
  clk: mmp: add mmp2 DT support for clock driver
It add the device tree support for pxa168, pxa910 and mmp2.

The final part of the patches
  arm: mmp: Make all the dts file to be compiled by Makefile
  arm: mmp: Make use of the DT supported clock
It changes the mmp platform to use device tree to parse the clocks.

Chao Xie (12):
  clk: mmp: add prefix "mmp" for structures defined for clk-frac
  clk: mmp: add spin lock for clk-frac
  clk: mmp: add init callback for clk-frac
  clk: mmp: move definiton of mmp_clk_frac to clk.h
  clk: mmp: add clock type mix
  clk: mmp: add mmp private gate clock
  clk: mmp: add basic support functions for DT support
  clk: mmp: add pxa168 DT support for clock driver
  clk: mmp: add pxa910 DT support for clock driver
  clk: mmp: add mmp2 DT support for clock driver
  arm: mmp: Make all the dts file to be compiled by Makefile
  arm: mmp: Make use of the DT supported clock

 .../bindings/clock/marvell-mmp2-clock.txt  |  20 +
 .../bindings/clock/marvell-pxa168-clock.txt|  20 +
 .../bindings/clock/marvell-pxa910-clock.txt|  20 +
 arch/arm/boot/dts/Makefile |   3 +
 arch/arm/boot/dts/mmp2-brownstone.dts  |   2 +-
 arch/arm/boot/dts/mmp2.dtsi|  20 +-
 arch/arm/boot/dts/pxa168-aspenite.dts  |   2 +-
 arch/arm/boot/dts/pxa168.dtsi  |  19 +-
 arch/arm/boot/dts/pxa910-dkb.dts   |   2 +-
 arch/arm/boot/dts/pxa910.dtsi  |  20 +-
 arch/arm/mach-mmp/Kconfig  |  10 +-
 arch/arm/mach-mmp/mmp-dt.c |  57 +--
 arch/arm/mach-mmp/mmp2-dt.c|  26 +-
 drivers/clk/mmp/Makefile   |   5 +-
 drivers/clk/mmp/clk-frac.c |  74 ++-
 drivers/clk/mmp/clk-gate.c | 133 ++
 drivers/clk/mmp/clk-mix.c  | 513 +
 drivers/clk/mmp/clk-mmp2.c |   6 +-
 drivers/clk/mmp/clk-of-mmp2.c  | 307 
 drivers/clk/mmp/clk-of-pxa168.c| 251 ++
 drivers/clk/mmp/clk-of-pxa910.c| 260 +++
 drivers/clk/mmp/clk-pxa168.c   |   6 +-
 drivers/clk/mmp/clk-pxa910.c   |   6 +-
 drivers/clk/mmp/clk.c  | 192 
 drivers/clk/mmp/clk.h  | 226 -
 include/dt-bindings/clock/marvell-mmp2.h   |  74 +++
 include/dt-bindings/clock/marvell-pxa168.h |  57 +++
 include/dt-bindings/clock/marvell-pxa910.h |  54 +++
 28 files changed, 2280 insertions(+), 105 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt
 create mode 100644 drivers/clk/mmp/clk-gate.c
 create mode 100644 drivers/clk/mmp/clk-mix.c
 create mode 100644 drivers/clk/mmp/clk-of-mmp2.c
 create mode 100644 drivers/clk/mmp/clk-of-pxa168.c
 create mode 100644 drivers/clk/mmp/clk-of-pxa910.c
 create mode 100644 drivers/clk/mmp/clk.c
 create mode 100644 include/dt-bindings/clock/marvell-mmp2.h
 create mode 100644 include/dt-bindings/clock/marvell-pxa168.h
 create mode 100644 include/dt-bindings/clock/marvell-pxa910.h

-- 
1.8.3.2

--
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 01/12] clk: mmp: add prefix "mmp" for structures defined for clk-frac

2014-08-25 Thread Chao Xie
From: Chao Xie 

The structures defined for clk-frac will be used out side
of clk-frac.c.
To avoid conflicts, add prefix "mmp" for these structures'
name.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c   | 23 ---
 drivers/clk/mmp/clk-mmp2.c   |  4 ++--
 drivers/clk/mmp/clk-pxa168.c |  4 ++--
 drivers/clk/mmp/clk-pxa910.c |  4 ++--
 drivers/clk/mmp/clk.h|  8 
 5 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 23a56f5..3fbc9ca 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -22,19 +22,19 @@
  * numerator/denominator = Fin / (Fout * factor)
  */
 
-#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw)
-struct clk_factor {
+#define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
+struct mmp_clk_factor {
struct clk_hw   hw;
void __iomem*base;
-   struct clk_factor_masks *masks;
-   struct clk_factor_tbl   *ftbl;
+   struct mmp_clk_factor_masks *masks;
+   struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
unsigned long rate = 0, prev_rate;
int i;
 
@@ -58,8 +58,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned 
long drate,
 static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
-   struct clk_factor_masks *masks = factor->masks;
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor->masks;
unsigned int val, num, den;
 
val = readl_relaxed(factor->base);
@@ -81,8 +81,8 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
 static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
-   struct clk_factor_masks *masks = factor->masks;
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor->masks;
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
@@ -118,10 +118,11 @@ static struct clk_ops clk_factor_ops = {
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
unsigned long flags, void __iomem *base,
-   struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl,
+   struct mmp_clk_factor_masks *masks,
+   struct mmp_clk_factor_tbl *ftbl,
unsigned int ftbl_cnt)
 {
-   struct clk_factor *factor;
+   struct mmp_clk_factor *factor;
struct clk_init_data init;
struct clk *clk;
 
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index b2721ca..7083f12 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -54,7 +54,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 14634, .den = 2165},/*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
{.num = 9679, .den = 5728}, /*58.9824MHZ */
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 014396b..75266ac 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -47,7 +47,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 8125, .den = 1536}, /*14.745MHZ */
 };
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index 9efc6a4..f817999 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -45,7 +45,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -53

[PATCH 03/12] clk: mmp: add init callback for clk-frac

2014-08-25 Thread Chao Xie
From: Chao Xie 

For the clk-frac, we need to make sure that the initial
clock rate is one item of the table.
If it is not, we use the first item in the table by default.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index e29d006..1876d2c 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -118,10 +118,50 @@ static int clk_factor_set_rate(struct clk_hw *hw, 
unsigned long drate,
return 0;
 }
 
+void clk_factor_init(struct clk_hw *hw)
+{
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor->masks;
+   u32 val, num, den;
+   int i;
+   unsigned long flags = 0;
+
+   if (factor->lock)
+   spin_lock_irqsave(factor->lock, flags);
+
+   val = readl(factor->base);
+
+   /* calculate numerator */
+   num = (val >> masks->num_shift) & masks->num_mask;
+
+   /* calculate denominator */
+   den = (val >> masks->den_shift) & masks->den_mask;
+
+   for (i = 0; i < factor->ftbl_cnt; i++)
+   if (den == factor->ftbl[i].den && num == factor->ftbl[i].num)
+   break;
+
+   if (i >= factor->ftbl_cnt) {
+   val &= ~(masks->num_mask << masks->num_shift);
+   val |= (factor->ftbl[0].num & masks->num_mask) <<
+   masks->num_shift;
+
+   val &= ~(masks->den_mask << masks->den_shift);
+   val |= (factor->ftbl[0].den & masks->den_mask) <<
+   masks->den_shift;
+
+   writel(val, factor->base);
+   }
+
+   if (factor->lock)
+   spin_unlock_irqrestore(factor->lock, flags);
+}
+
 static struct clk_ops clk_factor_ops = {
.recalc_rate = clk_factor_recalc_rate,
.round_rate = clk_factor_round_rate,
.set_rate = clk_factor_set_rate,
+   .init = clk_factor_init,
 };
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
-- 
1.8.3.2

--
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 08/12] clk: mmp: add pxa168 DT support for clock driver

2014-08-25 Thread Chao Xie
From: Chao Xie 

It adds the DT support for pxa168 clock subsystem.

Signed-off-by: Chao Xie 
---
 .../bindings/clock/marvell-pxa168-clock.txt|  20 ++
 drivers/clk/mmp/Makefile   |   2 +
 drivers/clk/mmp/clk-of-pxa168.c| 251 +
 include/dt-bindings/clock/marvell-pxa168.h |  57 +
 4 files changed, 330 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt
 create mode 100644 drivers/clk/mmp/clk-of-pxa168.c
 create mode 100644 include/dt-bindings/clock/marvell-pxa168.h

diff --git a/Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt 
b/Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt
new file mode 100644
index 000..888de87
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt
@@ -0,0 +1,20 @@
+* Marvell PXA168 Clock Controller
+
+The PXA168 clock subsystem generates and supplies clock to various
+controllers within the PXA168 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,pxa168-clock" - controller compatible with PXA168 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc". So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in .
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 32b5b90..37c14fa 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -4,6 +4,8 @@
 
 obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o
+
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
 obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
new file mode 100644
index 000..deac716
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -0,0 +1,251 @@
+/*
+ * pxa168 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+
+#define APBC_RTC   0x28
+#define APBC_TWSI0 0x2c
+#define APBC_KPC   0x30
+#define APBC_UART0 0x0
+#define APBC_UART1 0x4
+#define APBC_GPIO  0x8
+#define APBC_PWM0  0xc
+#define APBC_PWM1  0x10
+#define APBC_PWM2  0x14
+#define APBC_PWM3  0x18
+#define APBC_SSP0  0x81c
+#define APBC_SSP1  0x820
+#define APBC_SSP2  0x84c
+#define APBC_SSP3  0x858
+#define APBC_SSP4  0x85c
+#define APBC_TWSI1 0x6c
+#define APBC_UART2 0x70
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_CCIC0 0x50
+#define APMU_DFC   0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa168_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+   {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
+   {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 62400},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {PXA168_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+   {PXA168_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+   {PXA168_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+   {PXA168_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+   {PXA168_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0},
+   {PXA168_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+   {PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
+   {PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
+   {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
+   {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
+   {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
+   {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
+   {PXA168_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0},
+};
+
+static struct mmp_clk_factor_masks uart_facto

[PATCH 06/12] clk: mmp: add mmp private gate clock

2014-08-25 Thread Chao Xie
From: Chao Xie 

Some SOCes have this kind of the gate clock
1. There are some bits to control the gate not only one bit.
2. Some clocks has operations of "out of reset" and "enable".
   To enable clock, we need do "out of reset" and "enable".
   To disable clock, we may not need "set to reset". It depends
   on the SOCes' design.
3. It is not always that "1" is to enable while "0" is to disable
   when write register.

So we have to define the "mask", "enable_val", "disable_val" for
this kind of gate clock.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/Makefile   |   2 +-
 drivers/clk/mmp/clk-gate.c | 133 +
 drivers/clk/mmp/clk.h  |  21 +++
 3 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/clk-gate.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 8bfee860..2855f7b 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
new file mode 100644
index 000..adbd9d6
--- /dev/null
+++ b/drivers/clk/mmp/clk-gate.c
@@ -0,0 +1,133 @@
+/*
+ * mmp gate clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+
+/*
+ * Some clocks will have mutiple bits to enable the clocks, and
+ * the bits to disable the clock is not same as enabling bits.
+ */
+
+#define to_clk_mmp_gate(hw)container_of(hw, struct mmp_clk_gate, hw)
+
+static int mmp_clk_gate_enable(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   struct clk *clk = hw->clk;
+   unsigned long flags = 0;
+   unsigned long rate;
+   u32 tmp;
+
+   if (gate->lock)
+   spin_lock_irqsave(gate->lock, flags);
+
+   tmp = readl(gate->reg);
+   tmp &= ~gate->mask;
+   tmp |= gate->val_enable;
+   writel(tmp, gate->reg);
+
+   if (gate->lock)
+   spin_unlock_irqrestore(gate->lock, flags);
+
+   if (gate->flags & MMP_CLK_GATE_NEED_DELAY) {
+   rate = __clk_get_rate(clk);
+   /* Need delay 2 cycles. */
+   udelay(200/rate);
+   }
+
+   return 0;
+}
+
+static void mmp_clk_gate_disable(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   unsigned long flags = 0;
+   u32 tmp;
+
+   if (gate->lock)
+   spin_lock_irqsave(gate->lock, flags);
+
+   tmp = readl(gate->reg);
+   tmp &= ~gate->mask;
+   tmp |= gate->val_disable;
+   writel(tmp, gate->reg);
+
+   if (gate->lock)
+   spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   unsigned long flags = 0;
+   u32 tmp;
+
+   if (gate->lock)
+   spin_lock_irqsave(gate->lock, flags);
+
+   tmp = readl(gate->reg);
+
+   if (gate->lock)
+   spin_unlock_irqrestore(gate->lock, flags);
+
+   return (tmp & gate->mask) == gate->val_enable;
+}
+
+const struct clk_ops mmp_clk_gate_ops = {
+   .enable = mmp_clk_gate_enable,
+   .disable = mmp_clk_gate_disable,
+   .is_enabled = mmp_clk_gate_is_enabled,
+};
+
+struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
+   const char *parent_name, unsigned long flags,
+   void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
+   unsigned int gate_flags, spinlock_t *lock)
+{
+   struct mmp_clk_gate *gate;
+   struct clk *clk;
+   struct clk_init_data init;
+
+   /* allocate the gate */
+   gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+   if (!gate) {
+   pr_err("%s:%s could not allocate gate clk\n", __func__, name);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   init.name = name;
+   init.ops = _clk_gate_ops;
+   init.flags = flags | CLK_IS_BASIC;
+   init.parent_names = (parent_name ? _name : NULL);
+   init.num_parents = (parent_name ? 1 : 0);
+
+   /* struct clk_gate assignments */
+   gate->reg = reg;
+   gate->mask = mask;
+   gate->val_enable = val_enable;
+   gate->val_disable

[PATCH 04/12] clk: mmp: move definiton of mmp_clk_frac to clk.h

2014-08-25 Thread Chao Xie
From: Chao Xie 

Move the definition of structure of mmp_clk_frac to
clk.h.
So device tree support can use this structure.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c |  8 
 drivers/clk/mmp/clk.h  | 32 ++--
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 1876d2c..eeba52c 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -23,14 +23,6 @@
  */
 
 #define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
-struct mmp_clk_factor {
-   struct clk_hw   hw;
-   void __iomem*base;
-   struct mmp_clk_factor_masks *masks;
-   struct mmp_clk_factor_tbl   *ftbl;
-   unsigned intftbl_cnt;
-   spinlock_t *lock;
-};
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index b71b717..d267639 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -7,12 +7,14 @@
 #define APBC_NO_BUS_CTRL   BIT(0)
 #define APBC_POWER_CTRLBIT(1)
 
+
+/* Clock type "factor" */
 struct mmp_clk_factor_masks {
-   unsigned intfactor;
-   unsigned intnum_mask;
-   unsigned intden_mask;
-   unsigned intnum_shift;
-   unsigned intden_shift;
+   unsigned int factor;
+   unsigned int num_mask;
+   unsigned int den_mask;
+   unsigned int num_shift;
+   unsigned int den_shift;
 };
 
 struct mmp_clk_factor_tbl {
@@ -20,6 +22,21 @@ struct mmp_clk_factor_tbl {
unsigned int den;
 };
 
+struct mmp_clk_factor {
+   struct clk_hw hw;
+   void __iomem *base;
+   struct mmp_clk_factor_masks *masks;
+   struct mmp_clk_factor_tbl *ftbl;
+   unsigned int ftbl_cnt;
+   spinlock_t *lock;
+};
+
+extern struct clk *mmp_clk_register_factor(const char *name,
+   const char *parent_name, unsigned long flags,
+   void __iomem *base, struct mmp_clk_factor_masks *masks,
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t *lock);
+
 extern struct clk *mmp_clk_register_pll2(const char *name,
const char *parent_name, unsigned long flags);
 extern struct clk *mmp_clk_register_apbc(const char *name,
@@ -28,9 +45,4 @@ extern struct clk *mmp_clk_register_apbc(const char *name,
 extern struct clk *mmp_clk_register_apmu(const char *name,
const char *parent_name, void __iomem *base, u32 enable_mask,
spinlock_t *lock);
-extern struct clk *mmp_clk_register_factor(const char *name,
-   const char *parent_name, unsigned long flags,
-   void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
-   spinlock_t *lock);
 #endif
-- 
1.8.3.2

--
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 07/12] clk: mmp: add basic support functions for DT support

2014-08-25 Thread Chao Xie
From: Chao Xie 

In order to support DT for mmp SOC clocks, it defines
some basic APIs which are shared by all mmp SOC clock
units.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/Makefile |   2 +-
 drivers/clk/mmp/clk.c| 192 +++
 drivers/clk/mmp/clk.h| 106 +-
 3 files changed, 298 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/mmp/clk.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 2855f7b..32b5b90 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
new file mode 100644
index 000..cf038ef
--- /dev/null
+++ b/drivers/clk/mmp/clk.c
@@ -0,0 +1,192 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+
+void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
+   int nr_clks)
+{
+   static struct clk **clk_table;
+
+   clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
+   if (!clk_table)
+   return;
+
+   unit->clk_table = clk_table;
+   unit->nr_clks = nr_clks;
+   unit->clk_data.clks = clk_table;
+   unit->clk_data.clk_num = nr_clks;
+   of_clk_add_provider(np, of_clk_src_onecell_get, >clk_data);
+}
+
+void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_fixed_rate_clk *clks,
+   int size)
+{
+   int i;
+   struct clk *clk;
+
+   for (i = 0; i < size; i++) {
+   clk = clk_register_fixed_rate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   clks[i].fixed_rate);
+   if (IS_ERR(clk)) {
+   pr_err("%s: failed to register clock %s\n",
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit->clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_fixed_factor_clk *clks,
+   int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   clk = clk_register_fixed_factor(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags, clks[i].mult,
+   clks[i].div);
+   if (IS_ERR(clk)) {
+   pr_err("%s: failed to register clock %s\n",
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit->clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_general_gate_clk *clks,
+   void __iomem *base, int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   clk = clk_register_gate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   base + clks[i].offset,
+   clks[i].bit_idx,
+   clks[i].gate_flags,
+   clks[i].lock);
+
+   if (IS_ERR(clk)) {
+   pr_err("%s: failed to register clock %s\n",
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit->clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_gate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_gate_clk *clks,
+   void __iomem *base, int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   clk = mmp_clk_register_gate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   base + clks[i].offset,
+   clks[i].mask,
+   clks[i].val_enable,
+

[PATCH 12/12] arm: mmp: Make use of the DT supported clock

2014-08-25 Thread Chao Xie
From: Chao Xie 

Change the dtsi and dts file, soc initialization code to make
use of DT support clock.
So now in the code we do only need call of_clk_init to initialize
the clocks.

Signed-off-by: Chao Xie 
---
 arch/arm/boot/dts/mmp2.dtsi   | 18 ++
 arch/arm/boot/dts/pxa168.dtsi | 17 +
 arch/arm/boot/dts/pxa910.dtsi | 18 ++
 arch/arm/mach-mmp/Kconfig | 10 +++-
 arch/arm/mach-mmp/mmp-dt.c| 57 ++-
 arch/arm/mach-mmp/mmp2-dt.c   | 26 +++-
 6 files changed, 84 insertions(+), 62 deletions(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index e44f996..8a07a94 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -8,6 +8,7 @@
  */
 
 #include "skeleton.dtsi"
+#include 
 
 / {
aliases {
@@ -135,6 +136,7 @@
compatible = "mrvl,mmp-uart";
reg = <0xd403 0x1000>;
interrupts = <27>;
+   clocks = <_clocks MMP2_CLK_UART0>;
status = "disabled";
};
 
@@ -142,6 +144,7 @@
compatible = "mrvl,mmp-uart";
reg = <0xd4017000 0x1000>;
interrupts = <28>;
+   clocks = <_clocks MMP2_CLK_UART1>;
status = "disabled";
};
 
@@ -149,6 +152,7 @@
compatible = "mrvl,mmp-uart";
reg = <0xd4018000 0x1000>;
interrupts = <24>;
+   clocks = <_clocks MMP2_CLK_UART2>;
status = "disabled";
};
 
@@ -156,6 +160,7 @@
compatible = "mrvl,mmp-uart";
reg = <0xd4016000 0x1000>;
interrupts = <46>;
+   clocks = <_clocks MMP2_CLK_UART3>;
status = "disabled";
};
 
@@ -168,6 +173,7 @@
#gpio-cells = <2>;
interrupts = <49>;
interrupt-names = "gpio_mux";
+   clocks = <_clocks MMP2_CLK_GPIO>;
interrupt-controller;
#interrupt-cells = <1>;
ranges;
@@ -201,6 +207,7 @@
compatible = "mrvl,mmp-twsi";
reg = <0xd4011000 0x1000>;
interrupts = <7>;
+   clocks = <_clocks MMP2_CLK_TWSI0>;
#address-cells = <1>;
#size-cells = <0>;
mrvl,i2c-fast-mode;
@@ -211,6 +218,7 @@
compatible = "mrvl,mmp-twsi";
reg = <0xd4025000 0x1000>;
interrupts = <58>;
+   clocks = <_clocks MMP2_CLK_TWSI1>;
status = "disabled";
};
 
@@ -220,8 +228,18 @@
interrupts = <1 0>;
interrupt-names = "rtc 1Hz", "rtc alarm";
interrupt-parent = <>;
+   clocks = <_clocks MMP2_CLK_RTC>;
status = "disabled";
};
};
+
+   soc_clocks: clocks{
+   compatible = "marvell,mmp2-clock";
+   reg = <0xd405 0x1000>,
+ <0xd4282800 0x400>,
+ <0xd4015000 0x1000>;
+   reg-names = "mpmu", "apmu", "apbc";
+   #clock-cells = <1>;
+   };
};
 };
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index bfcbdef..e631dd6 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -8,6 +8,7 @@
  */
 
 #include "skeleton.dtsi"
+#include 
 
 / {
aliases {
@@ -59,6 +60,7 @@
compatible = "mrvl,mmp-uart";
reg = <0xd4017000 0x1000>;
interrupts = &

[PATCH 09/12] clk: mmp: add pxa910 DT support for clock driver

2014-08-25 Thread Chao Xie
From: Chao Xie 

It adds the DT support for pxa910 clock subsystem.

Signed-off-by: Chao Xie 
---
 .../bindings/clock/marvell-pxa910-clock.txt|  20 ++
 drivers/clk/mmp/Makefile   |   2 +-
 drivers/clk/mmp/clk-of-pxa910.c| 260 +
 include/dt-bindings/clock/marvell-pxa910.h |  54 +
 4 files changed, 335 insertions(+), 1 deletion(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt
 create mode 100644 drivers/clk/mmp/clk-of-pxa910.c
 create mode 100644 include/dt-bindings/clock/marvell-pxa910.h

diff --git a/Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt 
b/Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt
new file mode 100644
index 000..643b57b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt
@@ -0,0 +1,20 @@
+* Marvell PXA910 Clock Controller
+
+The PXA910 clock subsystem generates and supplies clock to various
+controllers within the PXA910 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,pxa910-clock" - controller compatible with PXA910 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 4 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc", "apbcp". So four reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in .
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 37c14fa..b803fac 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -4,7 +4,7 @@
 
 obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
-obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
new file mode 100644
index 000..f746376
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -0,0 +1,260 @@
+/*
+ * pxa910 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+
+#define APBC_RTC   0x28
+#define APBC_TWSI0 0x2c
+#define APBC_KPC   0x18
+#define APBC_UART0 0x0
+#define APBC_UART1 0x4
+#define APBC_GPIO  0x8
+#define APBC_PWM0  0xc
+#define APBC_PWM1  0x10
+#define APBC_PWM2  0x14
+#define APBC_PWM3  0x18
+#define APBC_SSP0  0x1c
+#define APBC_SSP1  0x20
+#define APBC_SSP2  0x4c
+#define APBCP_TWSI10x28
+#define APBCP_UART20x1c
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_CCIC0 0x50
+#define APMU_DFC   0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa910_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+   void __iomem *apbcp_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+   {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
+   {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 62400},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {PXA910_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+   {PXA910_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+   {PXA910_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+   {PXA910_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+   {PXA910_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0},
+   {PXA910_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+   {PXA910_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
+   {PXA910_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
+   {PXA910_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
+   {PXA910_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
+   {PXA910_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
+   {PXA910_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
+   {PXA910_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0},
+};
+
+static struct mmp_clk_fact

[PATCH 11/12] arm: mmp: Make all the dts file to be compiled by Makefile

2014-08-25 Thread Chao Xie
From: Chao Xie 

Add items in arch/arm/boot/dt/Makefile to compile the dtb
for mach-mmp.
Change the dts and dtsi file to use #include instead of \include\

Signed-off-by: Chao Xie 
---
 arch/arm/boot/dts/Makefile| 3 +++
 arch/arm/boot/dts/mmp2-brownstone.dts | 2 +-
 arch/arm/boot/dts/mmp2.dtsi   | 2 +-
 arch/arm/boot/dts/pxa168-aspenite.dts | 2 +-
 arch/arm/boot/dts/pxa168.dtsi | 2 +-
 arch/arm/boot/dts/pxa910-dkb.dts  | 2 +-
 arch/arm/boot/dts/pxa910.dtsi | 2 +-
 7 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index acb6b42..16f91c9 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -159,6 +159,9 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
kirkwood-ts419-6282.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
+   pxa910-dkb.dtb \
+   mmp2-brownstone.dtb
 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
imx25-eukrea-mbimxsd25-baseboard.dtb \
diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts 
b/arch/arm/boot/dts/mmp2-brownstone.dts
index 7f70a39..350208c 100644
--- a/arch/arm/boot/dts/mmp2-brownstone.dts
+++ b/arch/arm/boot/dts/mmp2-brownstone.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "mmp2.dtsi"
+#include "mmp2.dtsi"
 
 / {
model = "Marvell MMP2 Brownstone Development Board";
diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 4e8b08c..e44f996 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
aliases {
diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts 
b/arch/arm/boot/dts/pxa168-aspenite.dts
index e762fac..0a988b3 100644
--- a/arch/arm/boot/dts/pxa168-aspenite.dts
+++ b/arch/arm/boot/dts/pxa168-aspenite.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "pxa168.dtsi"
+#include "pxa168.dtsi"
 
 / {
model = "Marvell PXA168 Aspenite Development Board";
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index 975dad2..bfcbdef 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
aliases {
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..c82f281 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "pxa910.dtsi"
+#include "pxa910.dtsi"
 
 / {
model = "Marvell PXA910 DKB Development Board";
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 0247c62..884c6e8 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
aliases {
-- 
1.8.3.2

--
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 10/12] clk: mmp: add mmp2 DT support for clock driver

2014-08-25 Thread Chao Xie
From: Chao Xie 

It adds the DT support for mmp2 clock subsystem.

Signed-off-by: Chao Xie 
---
 .../bindings/clock/marvell-mmp2-clock.txt  |  20 ++
 drivers/clk/mmp/Makefile   |   1 +
 drivers/clk/mmp/clk-of-mmp2.c  | 307 +
 include/dt-bindings/clock/marvell-mmp2.h   |  74 +
 4 files changed, 402 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt
 create mode 100644 drivers/clk/mmp/clk-of-mmp2.c
 create mode 100644 include/dt-bindings/clock/marvell-mmp2.h

diff --git a/Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt 
b/Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt
new file mode 100644
index 000..ad4b409
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt
@@ -0,0 +1,20 @@
+* Marvell MMP2 Clock Controller
+
+The MMP2 clock subsystem generates and supplies clock to various
+controllers within the MMP2 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,mmp2-clock" - controller compatible with MMP2 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc". So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in .
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index b803fac..25a2bf1 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -5,6 +5,7 @@
 obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
 obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
+obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
new file mode 100644
index 000..3a3e9c2
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -0,0 +1,307 @@
+/*
+ * mmp2 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+
+#define APBC_RTC   0x0
+#define APBC_TWSI0 0x4
+#define APBC_TWSI1 0x8
+#define APBC_TWSI2 0xc
+#define APBC_TWSI3 0x10
+#define APBC_TWSI4 0x7c
+#define APBC_TWSI5 0x80
+#define APBC_KPC   0x18
+#define APBC_UART0 0x2c
+#define APBC_UART1 0x30
+#define APBC_UART2 0x34
+#define APBC_UART3 0x88
+#define APBC_GPIO  0x38
+#define APBC_PWM0  0x3c
+#define APBC_PWM1  0x40
+#define APBC_PWM2  0x44
+#define APBC_PWM3  0x48
+#define APBC_SSP0  0x50
+#define APBC_SSP1  0x54
+#define APBC_SSP2  0x58
+#define APBC_SSP3  0x5c
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_SDH2  0xe8
+#define APMU_SDH3  0xec
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_DISP1 0x110
+#define APMU_CCIC0 0x50
+#define APMU_CCIC1 0xf4
+#define MPMU_UART_PLL  0x14
+
+struct mmp2_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {MMP2_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+   {MMP2_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 2600},
+   {MMP2_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 8},
+   {MMP2_CLK_PLL2, "pll2", NULL, CLK_IS_ROOT, 96000},
+   {MMP2_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 48000},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {MMP2_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+   {MMP2_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+   {MMP2_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+   {MMP2_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+   {MMP2_CLK_PLL1_20, "pll1_20", "pll1_4", 1, 5, 0},
+   {MMP2_CLK_PLL1_3, "pll1_3", "pll1", 1, 3, 0},
+   {MMP2_CLK_PLL1_6, "pll1_6", "pll1_3", 1, 2, 0},
+   {MMP2_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+   {MMP2_CLK_PLL2_2, "pll2_2", "pll2", 1, 2, 0},
+   {MMP2_CLK_PLL2_4, "pll2_4", "pll2_2", 1, 2, 0},
+   {MMP2_CLK_PLL2_

[PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-08-25 Thread Chao Xie
From: Chao Xie 

The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.

Signed-off-by: Chao Xie 
---
 drivers/clk/mmp/clk-frac.c   | 11 ++-
 drivers/clk/mmp/clk-mmp2.c   |  2 +-
 drivers/clk/mmp/clk-pxa168.c |  2 +-
 drivers/clk/mmp/clk-pxa910.c |  2 +-
 drivers/clk/mmp/clk.h|  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 3fbc9ca..e29d006 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -29,6 +29,7 @@ struct mmp_clk_factor {
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
+   spinlock_t *lock;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
+   unsigned long flags = 0;
 
for (i = 0; i < factor->ftbl_cnt; i++) {
prev_rate = rate;
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
if (i > 0)
i--;
 
+   if (factor->lock)
+   spin_lock_irqsave(factor->lock, flags);
+
val = readl_relaxed(factor->base);
 
val &= ~(masks->num_mask << masks->num_shift);
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
 
writel_relaxed(val, factor->base);
 
+   if (factor->lock)
+   spin_unlock_irqrestore(factor->lock, flags);
+
return 0;
 }
 
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
unsigned long flags, void __iomem *base,
struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl,
-   unsigned int ftbl_cnt)
+   unsigned int ftbl_cnt, spinlock_t *lock)
 {
struct mmp_clk_factor *factor;
struct clk_init_data init;
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
factor->ftbl = ftbl;
factor->ftbl_cnt = ftbl_cnt;
factor->hw.init = 
+   factor->lock = lock;
 
init.name = name;
init.ops = _factor_ops;
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 7083f12..5c90a42 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 75266ac..93e967c 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index f817999..993abcd 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll =  mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL,
_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), _lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 3fe92be..b71b717 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name,
 extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsig

[PATCH 02/12] clk: mmp: add spin lock for clk-frac

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

The register used by clk-frac may be shared with
other clocks.
So it needs to use spin lock to protect the register
access.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c   | 11 ++-
 drivers/clk/mmp/clk-mmp2.c   |  2 +-
 drivers/clk/mmp/clk-pxa168.c |  2 +-
 drivers/clk/mmp/clk-pxa910.c |  2 +-
 drivers/clk/mmp/clk.h|  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 3fbc9ca..e29d006 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -29,6 +29,7 @@ struct mmp_clk_factor {
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
+   spinlock_t *lock;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
@@ -86,6 +87,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
+   unsigned long flags = 0;
 
for (i = 0; i  factor-ftbl_cnt; i++) {
prev_rate = rate;
@@ -97,6 +99,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
if (i  0)
i--;
 
+   if (factor-lock)
+   spin_lock_irqsave(factor-lock, flags);
+
val = readl_relaxed(factor-base);
 
val = ~(masks-num_mask  masks-num_shift);
@@ -107,6 +112,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned 
long drate,
 
writel_relaxed(val, factor-base);
 
+   if (factor-lock)
+   spin_unlock_irqrestore(factor-lock, flags);
+
return 0;
 }
 
@@ -120,7 +128,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
unsigned long flags, void __iomem *base,
struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl,
-   unsigned int ftbl_cnt)
+   unsigned int ftbl_cnt, spinlock_t *lock)
 {
struct mmp_clk_factor *factor;
struct clk_init_data init;
@@ -143,6 +151,7 @@ struct clk *mmp_clk_register_factor(const char *name, const 
char *parent_name,
factor-ftbl = ftbl;
factor-ftbl_cnt = ftbl_cnt;
factor-hw.init = init;
+   factor-lock = lock;
 
init.name = name;
init.ops = clk_factor_ops;
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 7083f12..5c90a42 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 75266ac..93e967c 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index f817999..993abcd 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll =  mmp_clk_register_factor(uart_pll, pll1_4, 0,
mpmu_base + MPMU_UART_PLL,
uart_factor_masks, uart_factor_tbl,
-   ARRAY_SIZE(uart_factor_tbl));
+   ARRAY_SIZE(uart_factor_tbl), clk_lock);
clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, uart_pll, NULL);
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 3fe92be..b71b717 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -31,5 +31,6 @@ extern struct clk *mmp_clk_register_apmu(const char *name,
 extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt);
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t

[PATCH 10/12] clk: mmp: add mmp2 DT support for clock driver

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

It adds the DT support for mmp2 clock subsystem.

Signed-off-by: Chao Xie chao@marvell.com
---
 .../bindings/clock/marvell-mmp2-clock.txt  |  20 ++
 drivers/clk/mmp/Makefile   |   1 +
 drivers/clk/mmp/clk-of-mmp2.c  | 307 +
 include/dt-bindings/clock/marvell-mmp2.h   |  74 +
 4 files changed, 402 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt
 create mode 100644 drivers/clk/mmp/clk-of-mmp2.c
 create mode 100644 include/dt-bindings/clock/marvell-mmp2.h

diff --git a/Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt 
b/Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt
new file mode 100644
index 000..ad4b409
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt
@@ -0,0 +1,20 @@
+* Marvell MMP2 Clock Controller
+
+The MMP2 clock subsystem generates and supplies clock to various
+controllers within the MMP2 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - marvell,mmp2-clock - controller compatible with MMP2 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  mpmu, apmu, apbc. So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in dt-bindings/clock/marvell-mmp2.h.
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index b803fac..25a2bf1 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -5,6 +5,7 @@
 obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
 obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
+obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
new file mode 100644
index 000..3a3e9c2
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -0,0 +1,307 @@
+/*
+ * mmp2 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie xiechao.m...@gmail.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/spinlock.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/err.h
+#include linux/of_address.h
+
+#include dt-bindings/clock/marvell-mmp2.h
+
+#include clk.h
+
+#define APBC_RTC   0x0
+#define APBC_TWSI0 0x4
+#define APBC_TWSI1 0x8
+#define APBC_TWSI2 0xc
+#define APBC_TWSI3 0x10
+#define APBC_TWSI4 0x7c
+#define APBC_TWSI5 0x80
+#define APBC_KPC   0x18
+#define APBC_UART0 0x2c
+#define APBC_UART1 0x30
+#define APBC_UART2 0x34
+#define APBC_UART3 0x88
+#define APBC_GPIO  0x38
+#define APBC_PWM0  0x3c
+#define APBC_PWM1  0x40
+#define APBC_PWM2  0x44
+#define APBC_PWM3  0x48
+#define APBC_SSP0  0x50
+#define APBC_SSP1  0x54
+#define APBC_SSP2  0x58
+#define APBC_SSP3  0x5c
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_SDH2  0xe8
+#define APMU_SDH3  0xec
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_DISP1 0x110
+#define APMU_CCIC0 0x50
+#define APMU_CCIC1 0xf4
+#define MPMU_UART_PLL  0x14
+
+struct mmp2_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {MMP2_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
+   {MMP2_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
+   {MMP2_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 8},
+   {MMP2_CLK_PLL2, pll2, NULL, CLK_IS_ROOT, 96000},
+   {MMP2_CLK_USB_PLL, usb_pll, NULL, CLK_IS_ROOT, 48000},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {MMP2_CLK_PLL1_2, pll1_2, pll1, 1, 2, 0},
+   {MMP2_CLK_PLL1_4, pll1_4, pll1_2, 1, 2, 0},
+   {MMP2_CLK_PLL1_8, pll1_8, pll1_4, 1, 2, 0},
+   {MMP2_CLK_PLL1_16, pll1_16, pll1_8, 1, 2, 0},
+   {MMP2_CLK_PLL1_20, pll1_20, pll1_4, 1, 5, 0},
+   {MMP2_CLK_PLL1_3, pll1_3, pll1, 1, 3, 0},
+   {MMP2_CLK_PLL1_6, pll1_6, pll1_3, 1, 2, 0},
+   {MMP2_CLK_PLL1_12, pll1_12, pll1_6, 1, 2, 0},
+   {MMP2_CLK_PLL2_2, pll2_2, pll2, 1, 2, 0},
+   {MMP2_CLK_PLL2_4, pll2_4, pll2_2, 1, 2, 0},
+   {MMP2_CLK_PLL2_8, pll2_8, pll2_4, 1, 2, 0},
+   {MMP2_CLK_PLL2_16, pll2_16, pll2_8, 1, 2, 0},
+   {MMP2_CLK_PLL2_3, pll2_3, pll2, 1, 3, 0

[PATCH 11/12] arm: mmp: Make all the dts file to be compiled by Makefile

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

Add items in arch/arm/boot/dt/Makefile to compile the dtb
for mach-mmp.
Change the dts and dtsi file to use #include instead of \include\

Signed-off-by: Chao Xie chao@marvell.com
---
 arch/arm/boot/dts/Makefile| 3 +++
 arch/arm/boot/dts/mmp2-brownstone.dts | 2 +-
 arch/arm/boot/dts/mmp2.dtsi   | 2 +-
 arch/arm/boot/dts/pxa168-aspenite.dts | 2 +-
 arch/arm/boot/dts/pxa168.dtsi | 2 +-
 arch/arm/boot/dts/pxa910-dkb.dts  | 2 +-
 arch/arm/boot/dts/pxa910.dtsi | 2 +-
 7 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index acb6b42..16f91c9 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -159,6 +159,9 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
kirkwood-ts419-6282.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
+   pxa910-dkb.dtb \
+   mmp2-brownstone.dtb
 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
imx25-eukrea-mbimxsd25-baseboard.dtb \
diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts 
b/arch/arm/boot/dts/mmp2-brownstone.dts
index 7f70a39..350208c 100644
--- a/arch/arm/boot/dts/mmp2-brownstone.dts
+++ b/arch/arm/boot/dts/mmp2-brownstone.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ mmp2.dtsi
+#include mmp2.dtsi
 
 / {
model = Marvell MMP2 Brownstone Development Board;
diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index 4e8b08c..e44f996 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ skeleton.dtsi
+#include skeleton.dtsi
 
 / {
aliases {
diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts 
b/arch/arm/boot/dts/pxa168-aspenite.dts
index e762fac..0a988b3 100644
--- a/arch/arm/boot/dts/pxa168-aspenite.dts
+++ b/arch/arm/boot/dts/pxa168-aspenite.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ pxa168.dtsi
+#include pxa168.dtsi
 
 / {
model = Marvell PXA168 Aspenite Development Board;
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index 975dad2..bfcbdef 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ skeleton.dtsi
+#include skeleton.dtsi
 
 / {
aliases {
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..c82f281 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ pxa910.dtsi
+#include pxa910.dtsi
 
 / {
model = Marvell PXA910 DKB Development Board;
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 0247c62..884c6e8 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -7,7 +7,7 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ skeleton.dtsi
+#include skeleton.dtsi
 
 / {
aliases {
-- 
1.8.3.2

--
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 12/12] arm: mmp: Make use of the DT supported clock

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

Change the dtsi and dts file, soc initialization code to make
use of DT support clock.
So now in the code we do only need call of_clk_init to initialize
the clocks.

Signed-off-by: Chao Xie chao@marvell.com
---
 arch/arm/boot/dts/mmp2.dtsi   | 18 ++
 arch/arm/boot/dts/pxa168.dtsi | 17 +
 arch/arm/boot/dts/pxa910.dtsi | 18 ++
 arch/arm/mach-mmp/Kconfig | 10 +++-
 arch/arm/mach-mmp/mmp-dt.c| 57 ++-
 arch/arm/mach-mmp/mmp2-dt.c   | 26 +++-
 6 files changed, 84 insertions(+), 62 deletions(-)

diff --git a/arch/arm/boot/dts/mmp2.dtsi b/arch/arm/boot/dts/mmp2.dtsi
index e44f996..8a07a94 100644
--- a/arch/arm/boot/dts/mmp2.dtsi
+++ b/arch/arm/boot/dts/mmp2.dtsi
@@ -8,6 +8,7 @@
  */
 
 #include skeleton.dtsi
+#include dt-bindings/clock/marvell-mmp2.h
 
 / {
aliases {
@@ -135,6 +136,7 @@
compatible = mrvl,mmp-uart;
reg = 0xd403 0x1000;
interrupts = 27;
+   clocks = soc_clocks MMP2_CLK_UART0;
status = disabled;
};
 
@@ -142,6 +144,7 @@
compatible = mrvl,mmp-uart;
reg = 0xd4017000 0x1000;
interrupts = 28;
+   clocks = soc_clocks MMP2_CLK_UART1;
status = disabled;
};
 
@@ -149,6 +152,7 @@
compatible = mrvl,mmp-uart;
reg = 0xd4018000 0x1000;
interrupts = 24;
+   clocks = soc_clocks MMP2_CLK_UART2;
status = disabled;
};
 
@@ -156,6 +160,7 @@
compatible = mrvl,mmp-uart;
reg = 0xd4016000 0x1000;
interrupts = 46;
+   clocks = soc_clocks MMP2_CLK_UART3;
status = disabled;
};
 
@@ -168,6 +173,7 @@
#gpio-cells = 2;
interrupts = 49;
interrupt-names = gpio_mux;
+   clocks = soc_clocks MMP2_CLK_GPIO;
interrupt-controller;
#interrupt-cells = 1;
ranges;
@@ -201,6 +207,7 @@
compatible = mrvl,mmp-twsi;
reg = 0xd4011000 0x1000;
interrupts = 7;
+   clocks = soc_clocks MMP2_CLK_TWSI0;
#address-cells = 1;
#size-cells = 0;
mrvl,i2c-fast-mode;
@@ -211,6 +218,7 @@
compatible = mrvl,mmp-twsi;
reg = 0xd4025000 0x1000;
interrupts = 58;
+   clocks = soc_clocks MMP2_CLK_TWSI1;
status = disabled;
};
 
@@ -220,8 +228,18 @@
interrupts = 1 0;
interrupt-names = rtc 1Hz, rtc alarm;
interrupt-parent = intcmux5;
+   clocks = soc_clocks MMP2_CLK_RTC;
status = disabled;
};
};
+
+   soc_clocks: clocks{
+   compatible = marvell,mmp2-clock;
+   reg = 0xd405 0x1000,
+ 0xd4282800 0x400,
+ 0xd4015000 0x1000;
+   reg-names = mpmu, apmu, apbc;
+   #clock-cells = 1;
+   };
};
 };
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
index bfcbdef..e631dd6 100644
--- a/arch/arm/boot/dts/pxa168.dtsi
+++ b/arch/arm/boot/dts/pxa168.dtsi
@@ -8,6 +8,7 @@
  */
 
 #include skeleton.dtsi
+#include dt-bindings/clock/marvell-pxa168.h
 
 / {
aliases {
@@ -59,6 +60,7 @@
compatible = mrvl,mmp-uart;
reg = 0xd4017000 0x1000;
interrupts = 27;
+   clocks = soc_clocks PXA168_CLK_UART0;
status = disabled;
};
 
@@ -66,6 +68,7 @@
compatible = mrvl,mmp-uart;
reg = 0xd4018000 0x1000;
interrupts = 28;
+   clocks = soc_clocks

[PATCH 09/12] clk: mmp: add pxa910 DT support for clock driver

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

It adds the DT support for pxa910 clock subsystem.

Signed-off-by: Chao Xie chao@marvell.com
---
 .../bindings/clock/marvell-pxa910-clock.txt|  20 ++
 drivers/clk/mmp/Makefile   |   2 +-
 drivers/clk/mmp/clk-of-pxa910.c| 260 +
 include/dt-bindings/clock/marvell-pxa910.h |  54 +
 4 files changed, 335 insertions(+), 1 deletion(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt
 create mode 100644 drivers/clk/mmp/clk-of-pxa910.c
 create mode 100644 include/dt-bindings/clock/marvell-pxa910.h

diff --git a/Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt 
b/Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt
new file mode 100644
index 000..643b57b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt
@@ -0,0 +1,20 @@
+* Marvell PXA910 Clock Controller
+
+The PXA910 clock subsystem generates and supplies clock to various
+controllers within the PXA910 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - marvell,pxa910-clock - controller compatible with PXA910 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 4 places in SOC has clock control logic:
+  mpmu, apmu, apbc, apbcp. So four reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in dt-bindings/clock/marvell-pxa910.h.
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 37c14fa..b803fac 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -4,7 +4,7 @@
 
 obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
-obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
new file mode 100644
index 000..f746376
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -0,0 +1,260 @@
+/*
+ * pxa910 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie xiechao.m...@gmail.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/spinlock.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/err.h
+#include linux/of_address.h
+
+#include dt-bindings/clock/marvell-pxa910.h
+
+#include clk.h
+
+#define APBC_RTC   0x28
+#define APBC_TWSI0 0x2c
+#define APBC_KPC   0x18
+#define APBC_UART0 0x0
+#define APBC_UART1 0x4
+#define APBC_GPIO  0x8
+#define APBC_PWM0  0xc
+#define APBC_PWM1  0x10
+#define APBC_PWM2  0x14
+#define APBC_PWM3  0x18
+#define APBC_SSP0  0x1c
+#define APBC_SSP1  0x20
+#define APBC_SSP2  0x4c
+#define APBCP_TWSI10x28
+#define APBCP_UART20x1c
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_CCIC0 0x50
+#define APMU_DFC   0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa910_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+   void __iomem *apbcp_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {PXA910_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
+   {PXA910_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
+   {PXA910_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 62400},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {PXA910_CLK_PLL1_2, pll1_2, pll1, 1, 2, 0},
+   {PXA910_CLK_PLL1_4, pll1_4, pll1_2, 1, 2, 0},
+   {PXA910_CLK_PLL1_8, pll1_8, pll1_4, 1, 2, 0},
+   {PXA910_CLK_PLL1_16, pll1_16, pll1_8, 1, 2, 0},
+   {PXA910_CLK_PLL1_6, pll1_6, pll1_2, 1, 3, 0},
+   {PXA910_CLK_PLL1_12, pll1_12, pll1_6, 1, 2, 0},
+   {PXA910_CLK_PLL1_24, pll1_24, pll1_12, 1, 2, 0},
+   {PXA910_CLK_PLL1_48, pll1_48, pll1_24, 1, 2, 0},
+   {PXA910_CLK_PLL1_96, pll1_96, pll1_48, 1, 2, 0},
+   {PXA910_CLK_PLL1_13, pll1_13, pll1, 1, 13, 0},
+   {PXA910_CLK_PLL1_13_1_5, pll1_13_1_5, pll1_13, 2, 3, 0},
+   {PXA910_CLK_PLL1_2_1_5, pll1_2_1_5, pll1_2, 2, 3, 0},
+   {PXA910_CLK_PLL1_3_16, pll1_3_16, pll1, 3, 16, 0},
+};
+
+static struct mmp_clk_factor_masks uart_factor_masks = {
+   .factor = 2,
+   .num_mask = 0x1fff,
+   .den_mask = 0x1fff,
+   .num_shift = 16,
+   .den_shift = 0,
+};
+
+static struct mmp_clk_factor_tbl

[PATCH 06/12] clk: mmp: add mmp private gate clock

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

Some SOCes have this kind of the gate clock
1. There are some bits to control the gate not only one bit.
2. Some clocks has operations of out of reset and enable.
   To enable clock, we need do out of reset and enable.
   To disable clock, we may not need set to reset. It depends
   on the SOCes' design.
3. It is not always that 1 is to enable while 0 is to disable
   when write register.

So we have to define the mask, enable_val, disable_val for
this kind of gate clock.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/Makefile   |   2 +-
 drivers/clk/mmp/clk-gate.c | 133 +
 drivers/clk/mmp/clk.h  |  21 +++
 3 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/clk-gate.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 8bfee860..2855f7b 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
new file mode 100644
index 000..adbd9d6
--- /dev/null
+++ b/drivers/clk/mmp/clk-gate.c
@@ -0,0 +1,133 @@
+/*
+ * mmp gate clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie chao@marvell.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/clk-provider.h
+#include linux/slab.h
+#include linux/io.h
+#include linux/err.h
+#include linux/delay.h
+
+#include clk.h
+
+/*
+ * Some clocks will have mutiple bits to enable the clocks, and
+ * the bits to disable the clock is not same as enabling bits.
+ */
+
+#define to_clk_mmp_gate(hw)container_of(hw, struct mmp_clk_gate, hw)
+
+static int mmp_clk_gate_enable(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   struct clk *clk = hw-clk;
+   unsigned long flags = 0;
+   unsigned long rate;
+   u32 tmp;
+
+   if (gate-lock)
+   spin_lock_irqsave(gate-lock, flags);
+
+   tmp = readl(gate-reg);
+   tmp = ~gate-mask;
+   tmp |= gate-val_enable;
+   writel(tmp, gate-reg);
+
+   if (gate-lock)
+   spin_unlock_irqrestore(gate-lock, flags);
+
+   if (gate-flags  MMP_CLK_GATE_NEED_DELAY) {
+   rate = __clk_get_rate(clk);
+   /* Need delay 2 cycles. */
+   udelay(200/rate);
+   }
+
+   return 0;
+}
+
+static void mmp_clk_gate_disable(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   unsigned long flags = 0;
+   u32 tmp;
+
+   if (gate-lock)
+   spin_lock_irqsave(gate-lock, flags);
+
+   tmp = readl(gate-reg);
+   tmp = ~gate-mask;
+   tmp |= gate-val_disable;
+   writel(tmp, gate-reg);
+
+   if (gate-lock)
+   spin_unlock_irqrestore(gate-lock, flags);
+}
+
+static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
+{
+   struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+   unsigned long flags = 0;
+   u32 tmp;
+
+   if (gate-lock)
+   spin_lock_irqsave(gate-lock, flags);
+
+   tmp = readl(gate-reg);
+
+   if (gate-lock)
+   spin_unlock_irqrestore(gate-lock, flags);
+
+   return (tmp  gate-mask) == gate-val_enable;
+}
+
+const struct clk_ops mmp_clk_gate_ops = {
+   .enable = mmp_clk_gate_enable,
+   .disable = mmp_clk_gate_disable,
+   .is_enabled = mmp_clk_gate_is_enabled,
+};
+
+struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
+   const char *parent_name, unsigned long flags,
+   void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
+   unsigned int gate_flags, spinlock_t *lock)
+{
+   struct mmp_clk_gate *gate;
+   struct clk *clk;
+   struct clk_init_data init;
+
+   /* allocate the gate */
+   gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+   if (!gate) {
+   pr_err(%s:%s could not allocate gate clk\n, __func__, name);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   init.name = name;
+   init.ops = mmp_clk_gate_ops;
+   init.flags = flags | CLK_IS_BASIC;
+   init.parent_names = (parent_name ? parent_name : NULL);
+   init.num_parents = (parent_name ? 1 : 0);
+
+   /* struct clk_gate assignments */
+   gate-reg = reg;
+   gate-mask = mask;
+   gate-val_enable = val_enable;
+   gate-val_disable = val_disable;
+   gate-flags = gate_flags;
+   gate-lock = lock;
+   gate-hw.init = init;
+
+   clk = clk_register(dev, gate-hw

[PATCH 04/12] clk: mmp: move definiton of mmp_clk_frac to clk.h

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

Move the definition of structure of mmp_clk_frac to
clk.h.
So device tree support can use this structure.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c |  8 
 drivers/clk/mmp/clk.h  | 32 ++--
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 1876d2c..eeba52c 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -23,14 +23,6 @@
  */
 
 #define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
-struct mmp_clk_factor {
-   struct clk_hw   hw;
-   void __iomem*base;
-   struct mmp_clk_factor_masks *masks;
-   struct mmp_clk_factor_tbl   *ftbl;
-   unsigned intftbl_cnt;
-   spinlock_t *lock;
-};
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index b71b717..d267639 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -7,12 +7,14 @@
 #define APBC_NO_BUS_CTRL   BIT(0)
 #define APBC_POWER_CTRLBIT(1)
 
+
+/* Clock type factor */
 struct mmp_clk_factor_masks {
-   unsigned intfactor;
-   unsigned intnum_mask;
-   unsigned intden_mask;
-   unsigned intnum_shift;
-   unsigned intden_shift;
+   unsigned int factor;
+   unsigned int num_mask;
+   unsigned int den_mask;
+   unsigned int num_shift;
+   unsigned int den_shift;
 };
 
 struct mmp_clk_factor_tbl {
@@ -20,6 +22,21 @@ struct mmp_clk_factor_tbl {
unsigned int den;
 };
 
+struct mmp_clk_factor {
+   struct clk_hw hw;
+   void __iomem *base;
+   struct mmp_clk_factor_masks *masks;
+   struct mmp_clk_factor_tbl *ftbl;
+   unsigned int ftbl_cnt;
+   spinlock_t *lock;
+};
+
+extern struct clk *mmp_clk_register_factor(const char *name,
+   const char *parent_name, unsigned long flags,
+   void __iomem *base, struct mmp_clk_factor_masks *masks,
+   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+   spinlock_t *lock);
+
 extern struct clk *mmp_clk_register_pll2(const char *name,
const char *parent_name, unsigned long flags);
 extern struct clk *mmp_clk_register_apbc(const char *name,
@@ -28,9 +45,4 @@ extern struct clk *mmp_clk_register_apbc(const char *name,
 extern struct clk *mmp_clk_register_apmu(const char *name,
const char *parent_name, void __iomem *base, u32 enable_mask,
spinlock_t *lock);
-extern struct clk *mmp_clk_register_factor(const char *name,
-   const char *parent_name, unsigned long flags,
-   void __iomem *base, struct mmp_clk_factor_masks *masks,
-   struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
-   spinlock_t *lock);
 #endif
-- 
1.8.3.2

--
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 07/12] clk: mmp: add basic support functions for DT support

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

In order to support DT for mmp SOC clocks, it defines
some basic APIs which are shared by all mmp SOC clock
units.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/Makefile |   2 +-
 drivers/clk/mmp/clk.c| 192 +++
 drivers/clk/mmp/clk.h| 106 +-
 3 files changed, 298 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/mmp/clk.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 2855f7b..32b5b90 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
new file mode 100644
index 000..cf038ef
--- /dev/null
+++ b/drivers/clk/mmp/clk.c
@@ -0,0 +1,192 @@
+#include linux/io.h
+#include linux/clk.h
+#include linux/clk-provider.h
+#include linux/clkdev.h
+#include linux/of.h
+#include linux/of_address.h
+
+#include clk.h
+
+void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
+   int nr_clks)
+{
+   static struct clk **clk_table;
+
+   clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
+   if (!clk_table)
+   return;
+
+   unit-clk_table = clk_table;
+   unit-nr_clks = nr_clks;
+   unit-clk_data.clks = clk_table;
+   unit-clk_data.clk_num = nr_clks;
+   of_clk_add_provider(np, of_clk_src_onecell_get, unit-clk_data);
+}
+
+void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_fixed_rate_clk *clks,
+   int size)
+{
+   int i;
+   struct clk *clk;
+
+   for (i = 0; i  size; i++) {
+   clk = clk_register_fixed_rate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   clks[i].fixed_rate);
+   if (IS_ERR(clk)) {
+   pr_err(%s: failed to register clock %s\n,
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit-clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_fixed_factor_clk *clks,
+   int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i  size; i++) {
+   clk = clk_register_fixed_factor(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags, clks[i].mult,
+   clks[i].div);
+   if (IS_ERR(clk)) {
+   pr_err(%s: failed to register clock %s\n,
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit-clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_general_gate_clk *clks,
+   void __iomem *base, int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i  size; i++) {
+   clk = clk_register_gate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   base + clks[i].offset,
+   clks[i].bit_idx,
+   clks[i].gate_flags,
+   clks[i].lock);
+
+   if (IS_ERR(clk)) {
+   pr_err(%s: failed to register clock %s\n,
+  __func__, clks[i].name);
+   continue;
+   }
+   if (clks[i].id)
+   unit-clk_table[clks[i].id] = clk;
+   }
+}
+
+void mmp_register_gate_clks(struct mmp_clk_unit *unit,
+   struct mmp_param_gate_clk *clks,
+   void __iomem *base, int size)
+{
+   struct clk *clk;
+   int i;
+
+   for (i = 0; i  size; i++) {
+   clk = mmp_clk_register_gate(NULL, clks[i].name,
+   clks[i].parent_name,
+   clks[i].flags,
+   base + clks[i].offset,
+   clks[i].mask,
+   clks[i].val_enable

[PATCH 08/12] clk: mmp: add pxa168 DT support for clock driver

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

It adds the DT support for pxa168 clock subsystem.

Signed-off-by: Chao Xie chao@marvell.com
---
 .../bindings/clock/marvell-pxa168-clock.txt|  20 ++
 drivers/clk/mmp/Makefile   |   2 +
 drivers/clk/mmp/clk-of-pxa168.c| 251 +
 include/dt-bindings/clock/marvell-pxa168.h |  57 +
 4 files changed, 330 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt
 create mode 100644 drivers/clk/mmp/clk-of-pxa168.c
 create mode 100644 include/dt-bindings/clock/marvell-pxa168.h

diff --git a/Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt 
b/Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt
new file mode 100644
index 000..888de87
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt
@@ -0,0 +1,20 @@
+* Marvell PXA168 Clock Controller
+
+The PXA168 clock subsystem generates and supplies clock to various
+controllers within the PXA168 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - marvell,pxa168-clock - controller compatible with PXA168 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  mpmu, apmu, apbc. So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in dt-bindings/clock/marvell-pxa168.h.
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 32b5b90..37c14fa 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -4,6 +4,8 @@
 
 obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o
+
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
 obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
new file mode 100644
index 000..deac716
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -0,0 +1,251 @@
+/*
+ * pxa168 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie xiechao.m...@gmail.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/spinlock.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/err.h
+#include linux/of_address.h
+
+#include dt-bindings/clock/marvell-pxa168.h
+
+#include clk.h
+
+#define APBC_RTC   0x28
+#define APBC_TWSI0 0x2c
+#define APBC_KPC   0x30
+#define APBC_UART0 0x0
+#define APBC_UART1 0x4
+#define APBC_GPIO  0x8
+#define APBC_PWM0  0xc
+#define APBC_PWM1  0x10
+#define APBC_PWM2  0x14
+#define APBC_PWM3  0x18
+#define APBC_SSP0  0x81c
+#define APBC_SSP1  0x820
+#define APBC_SSP2  0x84c
+#define APBC_SSP3  0x858
+#define APBC_SSP4  0x85c
+#define APBC_TWSI1 0x6c
+#define APBC_UART2 0x70
+#define APMU_SDH0  0x54
+#define APMU_SDH1  0x58
+#define APMU_USB   0x5c
+#define APMU_DISP0 0x4c
+#define APMU_CCIC0 0x50
+#define APMU_DFC   0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa168_clk_unit {
+   struct mmp_clk_unit unit;
+   void __iomem *mpmu_base;
+   void __iomem *apmu_base;
+   void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+   {PXA168_CLK_CLK32, clk32, NULL, CLK_IS_ROOT, 32768},
+   {PXA168_CLK_VCTCXO, vctcxo, NULL, CLK_IS_ROOT, 2600},
+   {PXA168_CLK_PLL1, pll1, NULL, CLK_IS_ROOT, 62400},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+   {PXA168_CLK_PLL1_2, pll1_2, pll1, 1, 2, 0},
+   {PXA168_CLK_PLL1_4, pll1_4, pll1_2, 1, 2, 0},
+   {PXA168_CLK_PLL1_8, pll1_8, pll1_4, 1, 2, 0},
+   {PXA168_CLK_PLL1_16, pll1_16, pll1_8, 1, 2, 0},
+   {PXA168_CLK_PLL1_6, pll1_6, pll1_2, 1, 3, 0},
+   {PXA168_CLK_PLL1_12, pll1_12, pll1_6, 1, 2, 0},
+   {PXA168_CLK_PLL1_24, pll1_24, pll1_12, 1, 2, 0},
+   {PXA168_CLK_PLL1_48, pll1_48, pll1_24, 1, 2, 0},
+   {PXA168_CLK_PLL1_96, pll1_96, pll1_48, 1, 2, 0},
+   {PXA168_CLK_PLL1_13, pll1_13, pll1, 1, 13, 0},
+   {PXA168_CLK_PLL1_13_1_5, pll1_13_1_5, pll1_13, 2, 3, 0},
+   {PXA168_CLK_PLL1_2_1_5, pll1_2_1_5, pll1_2, 2, 3, 0},
+   {PXA168_CLK_PLL1_3_16, pll1_3_16, pll1, 3, 16, 0},
+};
+
+static struct mmp_clk_factor_masks uart_factor_masks = {
+   .factor = 2,
+   .num_mask = 0x1fff,
+   .den_mask = 0x1fff,
+   .num_shift = 16,
+   .den_shift = 0,
+};
+
+static struct mmp_clk_factor_tbl uart_factor_tbl

[PATCH 01/12] clk: mmp: add prefix mmp for structures defined for clk-frac

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

The structures defined for clk-frac will be used out side
of clk-frac.c.
To avoid conflicts, add prefix mmp for these structures'
name.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c   | 23 ---
 drivers/clk/mmp/clk-mmp2.c   |  4 ++--
 drivers/clk/mmp/clk-pxa168.c |  4 ++--
 drivers/clk/mmp/clk-pxa910.c |  4 ++--
 drivers/clk/mmp/clk.h|  8 
 5 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index 23a56f5..3fbc9ca 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -22,19 +22,19 @@
  * numerator/denominator = Fin / (Fout * factor)
  */
 
-#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw)
-struct clk_factor {
+#define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
+struct mmp_clk_factor {
struct clk_hw   hw;
void __iomem*base;
-   struct clk_factor_masks *masks;
-   struct clk_factor_tbl   *ftbl;
+   struct mmp_clk_factor_masks *masks;
+   struct mmp_clk_factor_tbl   *ftbl;
unsigned intftbl_cnt;
 };
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
unsigned long rate = 0, prev_rate;
int i;
 
@@ -58,8 +58,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned 
long drate,
 static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
-   struct clk_factor_masks *masks = factor-masks;
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor-masks;
unsigned int val, num, den;
 
val = readl_relaxed(factor-base);
@@ -81,8 +81,8 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
 static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate)
 {
-   struct clk_factor *factor = to_clk_factor(hw);
-   struct clk_factor_masks *masks = factor-masks;
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor-masks;
int i;
unsigned long val;
unsigned long prev_rate, rate = 0;
@@ -118,10 +118,11 @@ static struct clk_ops clk_factor_ops = {
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
unsigned long flags, void __iomem *base,
-   struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl,
+   struct mmp_clk_factor_masks *masks,
+   struct mmp_clk_factor_tbl *ftbl,
unsigned int ftbl_cnt)
 {
-   struct clk_factor *factor;
+   struct mmp_clk_factor *factor;
struct clk_init_data init;
struct clk *clk;
 
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index b2721ca..7083f12 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -54,7 +54,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 14634, .den = 2165},/*14.745MHZ */
{.num = 3521, .den = 689},  /*19.23MHZ */
{.num = 9679, .den = 5728}, /*58.9824MHZ */
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 014396b..75266ac 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -47,7 +47,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff,
@@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 8125, .den = 1536}, /*14.745MHZ */
 };
 
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index 9efc6a4..f817999 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -45,7 +45,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2,
.num_mask = 0x1fff,
.den_mask = 0x1fff

[PATCH 03/12] clk: mmp: add init callback for clk-frac

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

For the clk-frac, we need to make sure that the initial
clock rate is one item of the table.
If it is not, we use the first item in the table by default.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/clk-frac.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index e29d006..1876d2c 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -118,10 +118,50 @@ static int clk_factor_set_rate(struct clk_hw *hw, 
unsigned long drate,
return 0;
 }
 
+void clk_factor_init(struct clk_hw *hw)
+{
+   struct mmp_clk_factor *factor = to_clk_factor(hw);
+   struct mmp_clk_factor_masks *masks = factor-masks;
+   u32 val, num, den;
+   int i;
+   unsigned long flags = 0;
+
+   if (factor-lock)
+   spin_lock_irqsave(factor-lock, flags);
+
+   val = readl(factor-base);
+
+   /* calculate numerator */
+   num = (val  masks-num_shift)  masks-num_mask;
+
+   /* calculate denominator */
+   den = (val  masks-den_shift)  masks-den_mask;
+
+   for (i = 0; i  factor-ftbl_cnt; i++)
+   if (den == factor-ftbl[i].den  num == factor-ftbl[i].num)
+   break;
+
+   if (i = factor-ftbl_cnt) {
+   val = ~(masks-num_mask  masks-num_shift);
+   val |= (factor-ftbl[0].num  masks-num_mask) 
+   masks-num_shift;
+
+   val = ~(masks-den_mask  masks-den_shift);
+   val |= (factor-ftbl[0].den  masks-den_mask) 
+   masks-den_shift;
+
+   writel(val, factor-base);
+   }
+
+   if (factor-lock)
+   spin_unlock_irqrestore(factor-lock, flags);
+}
+
 static struct clk_ops clk_factor_ops = {
.recalc_rate = clk_factor_recalc_rate,
.round_rate = clk_factor_round_rate,
.set_rate = clk_factor_set_rate,
+   .init = clk_factor_init,
 };
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
-- 
1.8.3.2

--
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 05/12] clk: mmp: add clock type mix

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

The clock type mix is a kind of clock combines div and mux.
This kind of clock can not allow to change div first then
mux or change mux first or div.
The reason is
1. Some clock has frequency change bit. Each time want to change
   the frequency, there are some operations based on this bit, and
   these operations are time-cost.
   Seperating div and mux change will make the process longer, and
   waste more time.
2. Seperting the div and mux may generate middle clock that the
   peripharals do not support. It may make the peripharals hang.

There are three kinds of this type of clock in all SOCes.
1. The clock has bit to trigger the frequency change.
2. Same as #1, but the operations for the bit is different
3. Do not have frequency change bit.

So this type of clock has implemented the callbacks
-determine_rate
-set_rate_and_parent
These callbacks can help to change the div and mux together.

Signed-off-by: Chao Xie chao@marvell.com
---
 drivers/clk/mmp/Makefile  |   2 +-
 drivers/clk/mmp/clk-mix.c | 513 ++
 drivers/clk/mmp/clk.h |  66 ++
 3 files changed, 580 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/clk-mix.c

diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 392d780..8bfee860 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,7 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c
new file mode 100644
index 000..b79742c
--- /dev/null
+++ b/drivers/clk/mmp/clk-mix.c
@@ -0,0 +1,513 @@
+/*
+ * mmp mix(div and mux) clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie chao@marvell.com
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed as is without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include linux/clk-provider.h
+#include linux/slab.h
+#include linux/io.h
+#include linux/err.h
+
+#include clk.h
+
+/*
+ * The mix clock is a clock combined mux and div type clock.
+ * Because the div field and mux field need to be set at same
+ * time, we can not divide it into 2 types of clock
+ */
+
+#define to_clk_mix(hw) container_of(hw, struct mmp_clk_mix, hw)
+
+static unsigned int _get_maxdiv(struct mmp_clk_mix *mix)
+{
+   unsigned int div_mask = (1  mix-reg_info.width_div) - 1;
+   unsigned int maxdiv = 0;
+   struct clk_div_table *clkt;
+
+   if (mix-div_flags  CLK_DIVIDER_ONE_BASED)
+   return div_mask;
+   if (mix-div_flags  CLK_DIVIDER_POWER_OF_TWO)
+   return 1  div_mask;
+   if (mix-div_table) {
+   for (clkt = mix-div_table; clkt-div; clkt++)
+   if (clkt-div  maxdiv)
+   maxdiv = clkt-div;
+   return maxdiv;
+   }
+   return div_mask + 1;
+}
+
+static unsigned int _get_div(struct mmp_clk_mix *mix, unsigned int val)
+{
+   struct clk_div_table *clkt;
+
+   if (mix-div_flags  CLK_DIVIDER_ONE_BASED)
+   return val;
+   if (mix-div_flags  CLK_DIVIDER_POWER_OF_TWO)
+   return 1  val;
+   if (mix-div_table) {
+   for (clkt = mix-div_table; clkt-div; clkt++)
+   if (clkt-val == val)
+   return clkt-div;
+   if (clkt-div == 0)
+   return 0;
+   }
+   return val + 1;
+}
+
+static unsigned int _get_mux(struct mmp_clk_mix *mix, unsigned int val)
+{
+   int num_parents = __clk_get_num_parents(mix-hw.clk);
+   int i;
+
+   if (mix-mux_flags  CLK_MUX_INDEX_BIT)
+   return ffs(val) - 1;
+   if (mix-mux_flags  CLK_MUX_INDEX_ONE)
+   return val - 1;
+   if (mix-mux_table) {
+   for (i = 0; i  num_parents; i++)
+   if (mix-mux_table[i] == val)
+   return i;
+   if (i == num_parents)
+   return 0;
+   }
+
+   return val;
+}
+static unsigned int _get_div_val(struct mmp_clk_mix *mix, unsigned int div)
+{
+   struct clk_div_table *clkt;
+
+   if (mix-div_flags  CLK_DIVIDER_ONE_BASED)
+   return div;
+   if (mix-div_flags  CLK_DIVIDER_POWER_OF_TWO)
+   return __ffs(div);
+   if (mix-div_table) {
+   for (clkt = mix-div_table; clkt-div; clkt++)
+   if (clkt-div == div)
+   return clkt-val;
+   if (clkt-div == 0)
+   return 0;
+   }
+
+   return div - 1;
+}
+
+static unsigned int _get_mux_val(struct mmp_clk_mix *mix, unsigned int mux)
+{
+   if (mix-mux_table

[PATCH 00/12] clk: mmp: clock device tree support

2014-08-25 Thread Chao Xie
From: Chao Xie chao@marvell.com

The patch set focuses at support device tree for clock.

The first part of the patches
  clk: mmp: add prefix mmp for structures defined for clk-frac
  clk: mmp: add spin lock for clk-frac
  clk: mmp: add init callback for clk-frac
  clk: mmp: move definiton of mmp_clk_frac to clk.h It enhances the clk-frac.

The second part of the patches
  clk: mmp: add clock type mix
  clk: mmp: add mmp private gate clock

The third part of the patches
  clk: mmp: add basic support functions for DT support
  clk: mmp: add pxa168 DT support for clock driver
  clk: mmp: add pxa910 DT support for clock driver
  clk: mmp: add mmp2 DT support for clock driver
It add the device tree support for pxa168, pxa910 and mmp2.

The final part of the patches
  arm: mmp: Make all the dts file to be compiled by Makefile
  arm: mmp: Make use of the DT supported clock
It changes the mmp platform to use device tree to parse the clocks.

Chao Xie (12):
  clk: mmp: add prefix mmp for structures defined for clk-frac
  clk: mmp: add spin lock for clk-frac
  clk: mmp: add init callback for clk-frac
  clk: mmp: move definiton of mmp_clk_frac to clk.h
  clk: mmp: add clock type mix
  clk: mmp: add mmp private gate clock
  clk: mmp: add basic support functions for DT support
  clk: mmp: add pxa168 DT support for clock driver
  clk: mmp: add pxa910 DT support for clock driver
  clk: mmp: add mmp2 DT support for clock driver
  arm: mmp: Make all the dts file to be compiled by Makefile
  arm: mmp: Make use of the DT supported clock

 .../bindings/clock/marvell-mmp2-clock.txt  |  20 +
 .../bindings/clock/marvell-pxa168-clock.txt|  20 +
 .../bindings/clock/marvell-pxa910-clock.txt|  20 +
 arch/arm/boot/dts/Makefile |   3 +
 arch/arm/boot/dts/mmp2-brownstone.dts  |   2 +-
 arch/arm/boot/dts/mmp2.dtsi|  20 +-
 arch/arm/boot/dts/pxa168-aspenite.dts  |   2 +-
 arch/arm/boot/dts/pxa168.dtsi  |  19 +-
 arch/arm/boot/dts/pxa910-dkb.dts   |   2 +-
 arch/arm/boot/dts/pxa910.dtsi  |  20 +-
 arch/arm/mach-mmp/Kconfig  |  10 +-
 arch/arm/mach-mmp/mmp-dt.c |  57 +--
 arch/arm/mach-mmp/mmp2-dt.c|  26 +-
 drivers/clk/mmp/Makefile   |   5 +-
 drivers/clk/mmp/clk-frac.c |  74 ++-
 drivers/clk/mmp/clk-gate.c | 133 ++
 drivers/clk/mmp/clk-mix.c  | 513 +
 drivers/clk/mmp/clk-mmp2.c |   6 +-
 drivers/clk/mmp/clk-of-mmp2.c  | 307 
 drivers/clk/mmp/clk-of-pxa168.c| 251 ++
 drivers/clk/mmp/clk-of-pxa910.c| 260 +++
 drivers/clk/mmp/clk-pxa168.c   |   6 +-
 drivers/clk/mmp/clk-pxa910.c   |   6 +-
 drivers/clk/mmp/clk.c  | 192 
 drivers/clk/mmp/clk.h  | 226 -
 include/dt-bindings/clock/marvell-mmp2.h   |  74 +++
 include/dt-bindings/clock/marvell-pxa168.h |  57 +++
 include/dt-bindings/clock/marvell-pxa910.h |  54 +++
 28 files changed, 2280 insertions(+), 105 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-mmp2-clock.txt
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-pxa168-clock.txt
 create mode 100644 
Documentation/devicetree/bindings/clock/marvell-pxa910-clock.txt
 create mode 100644 drivers/clk/mmp/clk-gate.c
 create mode 100644 drivers/clk/mmp/clk-mix.c
 create mode 100644 drivers/clk/mmp/clk-of-mmp2.c
 create mode 100644 drivers/clk/mmp/clk-of-pxa168.c
 create mode 100644 drivers/clk/mmp/clk-of-pxa910.c
 create mode 100644 drivers/clk/mmp/clk.c
 create mode 100644 include/dt-bindings/clock/marvell-mmp2.h
 create mode 100644 include/dt-bindings/clock/marvell-pxa168.h
 create mode 100644 include/dt-bindings/clock/marvell-pxa910.h

-- 
1.8.3.2

--
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/


  1   2   3   4   5   >