All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer
@ 2013-02-27 10:02 Akshay Saraswat
  2013-02-27 10:02 ` [U-Boot] [PATCH 1/9] Exynos: Change get_timer() to work correctly Akshay Saraswat
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

This patch set tries to fix few bugs in timer and re-organises PWM
clock code.

Akshay Saraswat (9):
  Exynos: Change get_timer() to work correctly
  Exynos: Add timer_get_us function
  Exynos: pwm: Fix two bugs in the exynos pwm configuration code
  Exynos: Avoid a divide by zero by specifying a non-zero period for
    pwm 4
  Exynos: Tidy up the pwm_config function in the exynos pwm driver
  Exynos: Add peripherial id for pwm
  Exynos: clock: Add generic api to get the clk freq
  Exynos: clock: Correct pwm source clk selection
  Exynos: pwm: Use generic api to get pwm clk freq

 arch/arm/cpu/armv7/exynos/clock.c         | 127 ++++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/s5p-common/pwm.c       |  45 +++++------
 arch/arm/cpu/armv7/s5p-common/timer.c     | 117 +++++++++++++--------------
 arch/arm/include/asm/arch-exynos/clk.h    |  27 +++++++
 arch/arm/include/asm/arch-exynos/periph.h |   5 ++
 board/samsung/smdk5250/setup.h            |   2 +-
 6 files changed, 237 insertions(+), 86 deletions(-)

-- 
1.8.0

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 1/9] Exynos: Change get_timer() to work correctly
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-28  1:26   ` Simon Glass
  2013-02-27 10:02 ` [U-Boot] [PATCH 2/9] Exynos: Add timer_get_us function Akshay Saraswat
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

At present get_timer() does not return sane values. It should count up
smoothly in milliscond intervals.

We can change the PWM to count down at 1MHz, providing a resolution
of 1us and a range of about an hour between required get_timer() calls.

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/cpu/armv7/s5p-common/pwm.c   |   6 ++
 arch/arm/cpu/armv7/s5p-common/timer.c | 100 +++++++++++++---------------------
 2 files changed, 44 insertions(+), 62 deletions(-)

diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
index 44d7bc3..3147f59 100644
--- a/arch/arm/cpu/armv7/s5p-common/pwm.c
+++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
@@ -174,6 +174,12 @@ int pwm_init(int pwm_id, int div, int invert)
 
 	/* set count value */
 	offset = pwm_id * 3;
+
+	/*
+	 * TODO(sjg): Use this as a countdown timer for now. We count down
+	 * from the maximum value to 0, then reset.
+	 */
+	timer_rate_hz = -1;
 	writel(timer_rate_hz, &pwm->tcntb0 + offset);
 
 	val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id));
diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
index e78c716..c48a297 100644
--- a/arch/arm/cpu/armv7/s5p-common/timer.c
+++ b/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -39,13 +39,33 @@ static inline struct s5p_timer *s5p_get_base_timer(void)
 	return (struct s5p_timer *)samsung_get_base_timer();
 }
 
+/**
+ * Read the countdown timer.
+ *
+ * This operates@1MHz and counts downwards. It will wrap about every
+ * hour (2^32 microseconds).
+ *
+ * @return current value of timer
+ */
+static unsigned long timer_get_us_down(void)
+{
+	struct s5p_timer *const timer = s5p_get_base_timer();
+
+	return readl(&timer->tcnto4);
+}
+
 int timer_init(void)
 {
 	/* PWM Timer 4 */
-	pwm_init(4, MUX_DIV_2, 0);
+	pwm_init(4, MUX_DIV_4, 0);
 	pwm_config(4, 0, 0);
 	pwm_enable(4);
 
+	/* Use this as the current monotonic time in us */
+	gd->arch.timer_reset_value = 0;
+
+	/* Use this as the last timer value we saw */
+	gd->arch.lastinc = timer_get_us_down();
 	reset_timer_masked();
 
 	return 0;
@@ -56,48 +76,28 @@ int timer_init(void)
  */
 unsigned long get_timer(unsigned long base)
 {
-	return get_timer_masked() - base;
+	ulong now = timer_get_us_down();
+
+	/*
+	 * Increment the time by the amount elapsed since the last read.
+	 * The timer may have wrapped around, but it makes no difference to
+	 * our arithmetic here.
+	 */
+	gd->arch.timer_reset_value += gd->arch.lastinc - now;
+	gd->arch.lastinc = now;
+
+	/* Divide by 1000 to convert from us to ms */
+	return gd->arch.timer_reset_value / 1000 - base;
 }
 
 /* delay x useconds */
 void __udelay(unsigned long usec)
 {
-	struct s5p_timer *const timer = s5p_get_base_timer();
-	unsigned long tmo, tmp, count_value;
-
-	count_value = readl(&timer->tcntb4);
-
-	if (usec >= 1000) {
-		/*
-		 * if "big" number, spread normalization
-		 * to seconds
-		 * 1. start to normalize for usec to ticks per sec
-		 * 2. find number of "ticks" to wait to achieve target
-		 * 3. finish normalize.
-		 */
-		tmo = usec / 1000;
-		tmo *= (CONFIG_SYS_HZ * count_value);
-		tmo /= 1000;
-	} else {
-		/* else small number, don't kill it prior to HZ multiply */
-		tmo = usec * CONFIG_SYS_HZ * count_value;
-		tmo /= (1000 * 1000);
-	}
-
-	/* get current timestamp */
-	tmp = get_current_tick();
-
-	/* if setting this fordward will roll time stamp */
-	/* reset "advancing" timestamp to 0, set lastinc value */
-	/* else, set advancing stamp wake up time */
-	if ((tmo + tmp + 1) < tmp)
-		reset_timer_masked();
-	else
-		tmo += tmp;
-
-	/* loop till event */
-	while (get_current_tick() < tmo)
-		;	/* nop */
+	unsigned long count_value;
+
+	count_value = timer_get_us_down();
+	while ((int)(count_value - timer_get_us_down()) < (int)usec)
+		;
 }
 
 void reset_timer_masked(void)
@@ -109,30 +109,6 @@ void reset_timer_masked(void)
 	gd->arch.tbl = 0;
 }
 
-unsigned long get_timer_masked(void)
-{
-	struct s5p_timer *const timer = s5p_get_base_timer();
-	unsigned long count_value = readl(&timer->tcntb4);
-
-	return get_current_tick() / count_value;
-}
-
-unsigned long get_current_tick(void)
-{
-	struct s5p_timer *const timer = s5p_get_base_timer();
-	unsigned long now = readl(&timer->tcnto4);
-	unsigned long count_value = readl(&timer->tcntb4);
-
-	if (gd->arch.lastinc >= now)
-		gd->arch.tbl += gd->arch.lastinc - now;
-	else
-		gd->arch.tbl += gd->arch.lastinc + count_value - now;
-
-	gd->arch.lastinc = now;
-
-	return gd->arch.tbl;
-}
-
 /*
  * This function is derived from PowerPC code (read timebase as long long).
  * On ARM it just returns the timer value.
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 2/9] Exynos: Add timer_get_us function
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
  2013-02-27 10:02 ` [U-Boot] [PATCH 1/9] Exynos: Change get_timer() to work correctly Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-28  1:27   ` Simon Glass
  2013-02-27 10:02 ` [U-Boot] [PATCH 3/9] Exynos: pwm: Fix two bugs in the exynos pwm configuration code Akshay Saraswat
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

timer_get_us returns the time in microseconds since a certain reference
point of history.  However, it does not guarantee to return an accurate
time after a long period; instead, it wraps around (that is, the
reference point is reset to some other point of history) after some
periods. The frequency of wrapping around is about an hour (or 2^32
microseconds).

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained

Signed-off-by: Che-Liang Chiou <clchiou@chromium.org>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/cpu/armv7/s5p-common/timer.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
index c48a297..de61405 100644
--- a/arch/arm/cpu/armv7/s5p-common/timer.c
+++ b/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -90,6 +90,21 @@ unsigned long get_timer(unsigned long base)
 	return gd->arch.timer_reset_value / 1000 - base;
 }
 
+unsigned long timer_get_us(void)
+{
+	static unsigned long base_time_us;
+
+	struct s5p_timer *const timer =
+		(struct s5p_timer *)samsung_get_base_timer();
+	unsigned long now_downward_us = readl(&timer->tcnto4);
+
+	if (!base_time_us)
+		base_time_us = now_downward_us;
+
+	/* Note that this timer counts downward. */
+	return base_time_us - now_downward_us;
+}
+
 /* delay x useconds */
 void __udelay(unsigned long usec)
 {
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 3/9] Exynos: pwm: Fix two bugs in the exynos pwm configuration code
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
  2013-02-27 10:02 ` [U-Boot] [PATCH 1/9] Exynos: Change get_timer() to work correctly Akshay Saraswat
  2013-02-27 10:02 ` [U-Boot] [PATCH 2/9] Exynos: Add timer_get_us function Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-28  1:29   ` Simon Glass
  2013-02-27 10:02 ` [U-Boot] [PATCH 4/9] Exynos: Avoid a divide by zero by specifying a non-zero period for pwm 4 Akshay Saraswat
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

First, the "div" value was being used incorrectly to compute the frequency of
the PWM timer. The value passed in is a constant which reflects the value
that would be found in a configuration register, 0 to 4. That should
correspond to a scaling factor of 1, 2, 4, 8, or 16, 1 << div, but div + 1 was
being used instead.

Second, the reset value of the timers were being calculated to give an overall
frequency, thrown out, and set to a maximum value. This was done so that PWM 4
could be used as the system clock by counting down from a high value, but it
was applied indiscriminantly. It should at most be applied only to PWM 4.

This change also takes the opportunity to tidy up the pwm_init function.

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained
Build and boot U-boot with this patch, backlight works properly.

Signed-off-by: Gabe Black <gabeblack@google.com>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/cpu/armv7/s5p-common/pwm.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
index 3147f59..02156d1 100644
--- a/arch/arm/cpu/armv7/s5p-common/pwm.c
+++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
@@ -143,7 +143,7 @@ int pwm_init(int pwm_id, int div, int invert)
 	u32 val;
 	const struct s5p_timer *pwm =
 			(struct s5p_timer *)samsung_get_base_timer();
-	unsigned long timer_rate_hz;
+	unsigned long ticks_per_period;
 	unsigned int offset, prescaler;
 
 	/*
@@ -167,20 +167,24 @@ int pwm_init(int pwm_id, int div, int invert)
 	val |= (div & 0xf) << MUX_DIV_SHIFT(pwm_id);
 	writel(val, &pwm->tcfg1);
 
-	timer_rate_hz = get_pwm_clk() / ((prescaler + 1) *
-			(div + 1));
+	if (pwm_id == 4) {
+		/*
+		 * TODO(sjg): Use this as a countdown timer for now. We count
+		 * down from the maximum value to 0, then reset.
+		 */
+		ticks_per_period = -1UL;
+	} else {
+		const unsigned long pwm_hz = 1000;
+		unsigned long timer_rate_hz = get_pwm_clk() /
+			((prescaler + 1) * (1 << div));
 
-	timer_rate_hz = timer_rate_hz / CONFIG_SYS_HZ;
+		ticks_per_period = timer_rate_hz / pwm_hz;
+	}
 
 	/* set count value */
 	offset = pwm_id * 3;
 
-	/*
-	 * TODO(sjg): Use this as a countdown timer for now. We count down
-	 * from the maximum value to 0, then reset.
-	 */
-	timer_rate_hz = -1;
-	writel(timer_rate_hz, &pwm->tcntb0 + offset);
+	writel(ticks_per_period, &pwm->tcntb0 + offset);
 
 	val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id));
 	if (invert && (pwm_id < 4))
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 4/9] Exynos: Avoid a divide by zero by specifying a non-zero period for pwm 4
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
                   ` (2 preceding siblings ...)
  2013-02-27 10:02 ` [U-Boot] [PATCH 3/9] Exynos: pwm: Fix two bugs in the exynos pwm configuration code Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-28  1:29   ` Simon Glass
  2013-02-27 10:02 ` [U-Boot] [PATCH 5/9] Exynos: Tidy up the pwm_config function in the exynos pwm driver Akshay Saraswat
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

The pwm_config function in the exynos pwm driver divides by its period
period parameter. A function was calling pwm_config with a 0ns period and a
0ns duty cycle. That doesn't actually make any sense physically, and results
in a divide by zero in the driver. This change changes the paremters to be a
100000ns period and duty cycle.

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained
Build and boot U-boot with this patch, backlight works properly.

Signed-off-by: Gabe Black <gabeblack@google.com>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/cpu/armv7/s5p-common/timer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
index de61405..6a0fa58 100644
--- a/arch/arm/cpu/armv7/s5p-common/timer.c
+++ b/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -58,7 +58,7 @@ int timer_init(void)
 {
 	/* PWM Timer 4 */
 	pwm_init(4, MUX_DIV_4, 0);
-	pwm_config(4, 0, 0);
+	pwm_config(4, 100000, 100000);
 	pwm_enable(4);
 
 	/* Use this as the current monotonic time in us */
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 5/9] Exynos: Tidy up the pwm_config function in the exynos pwm driver
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
                   ` (3 preceding siblings ...)
  2013-02-27 10:02 ` [U-Boot] [PATCH 4/9] Exynos: Avoid a divide by zero by specifying a non-zero period for pwm 4 Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-28  1:30   ` Simon Glass
  2013-02-27 10:02 ` [U-Boot] [PATCH 6/9] Exynos: Add peripherial id for pwm Akshay Saraswat
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

Some small fixes in the exynos pwm driver:

1. NS_IN_HZ is non-sensical since these are not compatible units. This
constant actually describes the number of nanoseconds in a second. Renamed it
to NS_IN_SEC. Also dropped the unnecessary parenthesis.
2. The variable "period" is not used to hold a period, it's used to hold a
frequency. Renamed it to "frequency".
3. tcmp is an unsigned value, so (tcmp < 0) will never be true and the if
which checks that condition will never execute. Also, there should be no
problem if the pwm never switches, so there's no reason to subtract one from
tcmp and therefore no reason to compare it against zero. Removed both ifs. If
they weren't removed, tcmp should be a signed value.
4. Add a check for a 0 period.

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained
Build and boot U-boot with this patch, backlight works properly.

Signed-off-by: Gabe Black <gabeblack@google.com>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/cpu/armv7/s5p-common/pwm.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
index 02156d1..6f401b8 100644
--- a/arch/arm/cpu/armv7/s5p-common/pwm.c
+++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
@@ -70,7 +70,7 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
 	return tin_parent_rate / 16;
 }
 
-#define NS_IN_HZ (1000000000UL)
+#define NS_IN_SEC 1000000000UL
 
 int pwm_config(int pwm_id, int duty_ns, int period_ns)
 {
@@ -79,7 +79,7 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns)
 	unsigned int offset;
 	unsigned long tin_rate;
 	unsigned long tin_ns;
-	unsigned long period;
+	unsigned long frequency;
 	unsigned long tcon;
 	unsigned long tcnt;
 	unsigned long tcmp;
@@ -89,34 +89,24 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns)
 	 * fact that anything faster than 1GHz is easily representable
 	 * by 32bits.
 	 */
-	if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+	if (period_ns > NS_IN_SEC || duty_ns > NS_IN_SEC || period_ns == 0)
 		return -ERANGE;
 
 	if (duty_ns > period_ns)
 		return -EINVAL;
 
-	period = NS_IN_HZ / period_ns;
+	frequency = NS_IN_SEC / period_ns;
 
 	/* Check to see if we are changing the clock rate of the PWM */
-	tin_rate = pwm_calc_tin(pwm_id, period);
+	tin_rate = pwm_calc_tin(pwm_id, frequency);
 
-	tin_ns = NS_IN_HZ / tin_rate;
+	tin_ns = NS_IN_SEC / tin_rate;
 	tcnt = period_ns / tin_ns;
 
 	/* Note, counters count down */
 	tcmp = duty_ns / tin_ns;
 	tcmp = tcnt - tcmp;
 
-	/*
-	 * the pwm hw only checks the compare register after a decrement,
-	 * so the pin never toggles if tcmp = tcnt
-	 */
-	if (tcmp == tcnt)
-		tcmp--;
-
-	if (tcmp < 0)
-		tcmp = 0;
-
 	/* Update the PWM register block. */
 	offset = pwm_id * 3;
 	if (pwm_id < 4) {
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 6/9] Exynos: Add peripherial id for pwm
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
                   ` (4 preceding siblings ...)
  2013-02-27 10:02 ` [U-Boot] [PATCH 5/9] Exynos: Tidy up the pwm_config function in the exynos pwm driver Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-28  1:31   ` Simon Glass
  2013-02-27 10:02 ` [U-Boot] [PATCH 7/9] Exynos: clock: Add generic api to get the clk freq Akshay Saraswat
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

Add peripherial id for pwm inorder to support
generic api to get the clk frequency

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained
Build and boot U-boot with this patch, backlight works properly.

Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/include/asm/arch-exynos/periph.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h
index 89bcdfc..e5aed4b 100644
--- a/arch/arm/include/asm/arch-exynos/periph.h
+++ b/arch/arm/include/asm/arch-exynos/periph.h
@@ -61,6 +61,11 @@ enum periph_id {
 	PERIPH_ID_SPI3,
 	PERIPH_ID_SPI4,
 	PERIPH_ID_SDMMC4,
+	PERIPH_ID_PWM0,
+	PERIPH_ID_PWM1,
+	PERIPH_ID_PWM2,
+	PERIPH_ID_PWM3,
+	PERIPH_ID_PWM4,
 
 	PERIPH_ID_COUNT,
 	PERIPH_ID_NONE = -1,
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 7/9] Exynos: clock: Add generic api to get the clk freq
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
                   ` (5 preceding siblings ...)
  2013-02-27 10:02 ` [U-Boot] [PATCH 6/9] Exynos: Add peripherial id for pwm Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-28  1:35   ` Simon Glass
  2013-02-27 10:02 ` [U-Boot] [PATCH 8/9] Exynos: clock: Correct pwm source clk selection Akshay Saraswat
  2013-02-27 10:02 ` [U-Boot] [PATCH 9/9] Exynos: pwm: Use generic api to get pwm clk freq Akshay Saraswat
  8 siblings, 1 reply; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

Add generic api to get the frequency of the required peripherial. This
API gets the source clock frequency and returns the required frequency
by dividing with first and second dividers based on the requirement.

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained
Build and boot U-boot with this patch, backlight works properly.

Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/cpu/armv7/exynos/clock.c      | 127 +++++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-exynos/clk.h |  27 +++++++
 2 files changed, 154 insertions(+)

diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
index 956427c..a7a3066 100644
--- a/arch/arm/cpu/armv7/exynos/clock.c
+++ b/arch/arm/cpu/armv7/exynos/clock.c
@@ -27,6 +27,39 @@
 #include <asm/arch/clk.h>
 #include <asm/arch/periph.h>
 
+/* src_bit div_bit prediv_bit */
+static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
+	{0,	0,	-1},
+	{4,	4,	-1},
+	{8,	8,	-1},
+	{12,	12,	-1},
+	{0,	0,	8},
+	{4,	16,	24},
+	{8,	0,	8},
+	{12,	16,	24},
+	{-1,	-1,	-1},
+	{16,	0,	8},
+	{20,	16,	24},
+	{24,	0,	8},
+	{0,	0,	4},
+	{4,	12,	16},
+	{-1,	-1,	-1},
+	{-1,	-1,	-1},
+	{-1,	24,	0},
+	{-1,	24,	0},
+	{-1,	24,	0},
+	{-1,	24,	0},
+	{-1,	24,	0},
+	{-1,	24,	0},
+	{-1,	24,	0},
+	{-1,	24,	0},
+	{24,	0,	-1},
+	{24,	0,	-1},
+	{24,	0,	-1},
+	{24,	0,	-1},
+	{24,	0,	-1},
+};
+
 /* Epll Clock division values to achive different frequency output */
 static struct set_epll_con_val exynos5_epll_div[] = {
 	{ 192000000, 0, 48, 3, 1, 0 },
@@ -201,6 +234,100 @@ static unsigned long exynos5_get_pll_clk(int pllreg)
 	return fout;
 }
 
+unsigned long exynos5_get_periph_rate(enum periph_id peripheral)
+{
+	struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
+	unsigned long sclk, sub_clk;
+	unsigned int src, div, sub_div;
+	struct exynos5_clock *clk =
+			(struct exynos5_clock *)samsung_get_base_clock();
+
+	switch (peripheral) {
+	case PERIPH_ID_UART0:
+	case PERIPH_ID_UART1:
+	case PERIPH_ID_UART2:
+	case PERIPH_ID_UART3:
+		src = readl(&clk->src_peric0);
+		div = readl(&clk->div_peric0);
+		break;
+	case PERIPH_ID_PWM0:
+	case PERIPH_ID_PWM1:
+	case PERIPH_ID_PWM2:
+	case PERIPH_ID_PWM3:
+	case PERIPH_ID_PWM4:
+		src = readl(&clk->src_peric0);
+		div = readl(&clk->div_peric3);
+		break;
+	case PERIPH_ID_SPI0:
+	case PERIPH_ID_SPI1:
+		src = readl(&clk->src_peric1);
+		div = readl(&clk->div_peric1);
+		break;
+	case PERIPH_ID_SPI2:
+		src = readl(&clk->src_peric1);
+		div = readl(&clk->div_peric2);
+		break;
+	case PERIPH_ID_SPI3:
+	case PERIPH_ID_SPI4:
+		src = readl(&clk->sclk_src_isp);
+		div = readl(&clk->sclk_div_isp);
+		break;
+	case PERIPH_ID_SDMMC0:
+	case PERIPH_ID_SDMMC1:
+	case PERIPH_ID_SDMMC2:
+	case PERIPH_ID_SDMMC3:
+		src = readl(&clk->src_fsys);
+		div = readl(&clk->div_fsys1);
+		break;
+	case PERIPH_ID_I2C0:
+	case PERIPH_ID_I2C1:
+	case PERIPH_ID_I2C2:
+	case PERIPH_ID_I2C3:
+	case PERIPH_ID_I2C4:
+	case PERIPH_ID_I2C5:
+	case PERIPH_ID_I2C6:
+	case PERIPH_ID_I2C7:
+		sclk = exynos5_get_pll_clk(MPLL);
+		sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) & 0x7) + 1;
+		div = ((readl(&clk->div_top0) >> bit_info->prediv_bit) & 0x7) + 1;
+		return (sclk / sub_div) / div;
+	default:
+		debug("%s: invalid peripheral %d", __func__, peripheral);
+		return -1;
+	};
+
+	src = (src >> bit_info->src_bit) & 0xf;
+	if (src == SRC_MPLL)
+		sclk = exynos5_get_pll_clk(MPLL);
+	else if (src == SRC_EPLL)
+		sclk = exynos5_get_pll_clk(EPLL);
+	else if (src == SRC_VPLL)
+		sclk = exynos5_get_pll_clk(VPLL);
+	else
+		return 0;
+
+	sub_div = (div >> bit_info->div_bit) & 0xf;
+	sub_clk = sclk / (sub_div + 1);
+
+	if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
+		div = (div >> bit_info->prediv_bit) & 0xff;
+		return sub_clk / (div + 1);
+	}
+
+	return sub_clk;
+}
+
+unsigned long clock_get_periph_rate(enum periph_id peripheral)
+{
+	if (cpu_is_exynos5())
+		return exynos5_get_periph_rate(peripheral);
+	else {
+		if (proid_is_exynos4412())
+			return 0;
+		return 0;
+	}
+}
+
 /* exynos4: return ARM clock frequency */
 static unsigned long exynos4_get_arm_clk(void)
 {
diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
index 1935b0b..b459b16 100644
--- a/arch/arm/include/asm/arch-exynos/clk.h
+++ b/arch/arm/include/asm/arch-exynos/clk.h
@@ -22,6 +22,8 @@
 #ifndef __ASM_ARM_ARCH_CLK_H_
 #define __ASM_ARM_ARCH_CLK_H_
 
+#include <asm/arch/periph.h>
+
 #define APLL	0
 #define MPLL	1
 #define EPLL	2
@@ -29,6 +31,22 @@
 #define VPLL	4
 #define BPLL	5
 
+enum pll_src_bit {
+	SRC_MPLL = 6,
+	SRC_EPLL,
+	SRC_VPLL,
+};
+
+/* *
+ * This structure is to store the src bit, div bit and prediv bit
+ * positions of the peripheral clocks of the src and div registers
+ */
+struct clk_bit_info {
+	int src_bit;
+	int div_bit;
+	int prediv_bit;
+};
+
 unsigned long get_pll_clk(int pllreg);
 unsigned long get_arm_clk(void);
 unsigned long get_i2c_clk(void);
@@ -44,4 +62,13 @@ int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq);
 int set_epll_clk(unsigned long rate);
 int set_spi_clk(int periph_id, unsigned int rate);
 
+/**
+ * get the clk frequency of the required peripherial
+ *
+ * @param peripherial	Peripherial id
+ *
+ * @return frequency of the peripherial clk
+ */
+unsigned long clock_get_periph_rate(enum periph_id peripheral);
+
 #endif
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 8/9] Exynos: clock: Correct pwm source clk selection
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
                   ` (6 preceding siblings ...)
  2013-02-27 10:02 ` [U-Boot] [PATCH 7/9] Exynos: clock: Add generic api to get the clk freq Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-27 10:02 ` [U-Boot] [PATCH 9/9] Exynos: pwm: Use generic api to get pwm clk freq Akshay Saraswat
  8 siblings, 0 replies; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

MPLL is selected as the source clk of pwm by default

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained
Build and boot U-boot with this patch, backlight works properly.

Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 board/samsung/smdk5250/setup.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h
index a159601..34d8bc3 100644
--- a/board/samsung/smdk5250/setup.h
+++ b/board/samsung/smdk5250/setup.h
@@ -343,7 +343,7 @@
 #define TOP2_VAL		0x0110000
 
 /* CLK_SRC_PERIC0 */
-#define PWM_SEL		0
+#define PWM_SEL		6
 #define UART3_SEL	6
 #define UART2_SEL	6
 #define UART1_SEL	6
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 9/9] Exynos: pwm: Use generic api to get pwm clk freq
  2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
                   ` (7 preceding siblings ...)
  2013-02-27 10:02 ` [U-Boot] [PATCH 8/9] Exynos: clock: Correct pwm source clk selection Akshay Saraswat
@ 2013-02-27 10:02 ` Akshay Saraswat
  2013-02-28  1:36   ` Simon Glass
  2013-02-28  5:33   ` Rajeshwari Birje
  8 siblings, 2 replies; 19+ messages in thread
From: Akshay Saraswat @ 2013-02-27 10:02 UTC (permalink / raw)
  To: u-boot

Use generic api to get the pwm clock frequency

TEST=sf probe 1:0; time sf read 40008000 0 1000
Try with different numbers of bytes and see that sane values are obtained
Build and boot U-boot with this patch, backlight works properly.

Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
 arch/arm/cpu/armv7/s5p-common/pwm.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
index 6f401b8..06e0351 100644
--- a/arch/arm/cpu/armv7/s5p-common/pwm.c
+++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
@@ -28,6 +28,7 @@
 #include <asm/io.h>
 #include <asm/arch/pwm.h>
 #include <asm/arch/clk.h>
+#include <asm/arch/periph.h>
 
 int pwm_enable(int pwm_id)
 {
@@ -60,7 +61,7 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
 	unsigned long tin_parent_rate;
 	unsigned int div;
 
-	tin_parent_rate = get_pwm_clk();
+	tin_parent_rate = clock_get_periph_rate(PERIPH_ID_PWM0);
 
 	for (div = 2; div <= 16; div *= 2) {
 		if ((tin_parent_rate / (div << 16)) < freq)
@@ -165,8 +166,8 @@ int pwm_init(int pwm_id, int div, int invert)
 		ticks_per_period = -1UL;
 	} else {
 		const unsigned long pwm_hz = 1000;
-		unsigned long timer_rate_hz = get_pwm_clk() /
-			((prescaler + 1) * (1 << div));
+		unsigned long timer_rate_hz = clock_get_periph_rate(
+			PERIPH_ID_PWM0) / ((prescaler + 1) * (1 << div));
 
 		ticks_per_period = timer_rate_hz / pwm_hz;
 	}
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 1/9] Exynos: Change get_timer() to work correctly
  2013-02-27 10:02 ` [U-Boot] [PATCH 1/9] Exynos: Change get_timer() to work correctly Akshay Saraswat
@ 2013-02-28  1:26   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2013-02-28  1:26 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> At present get_timer() does not return sane values. It should count up
> smoothly in milliscond intervals.
>
> We can change the PWM to count down at 1MHz, providing a resolution
> of 1us and a range of about an hour between required get_timer() calls.
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>

Acked-by: Simon Glass <sjg@chromium.org>

> ---
>  arch/arm/cpu/armv7/s5p-common/pwm.c   |   6 ++
>  arch/arm/cpu/armv7/s5p-common/timer.c | 100 +++++++++++++---------------------
>  2 files changed, 44 insertions(+), 62 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
> index 44d7bc3..3147f59 100644
> --- a/arch/arm/cpu/armv7/s5p-common/pwm.c
> +++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
> @@ -174,6 +174,12 @@ int pwm_init(int pwm_id, int div, int invert)
>
>         /* set count value */
>         offset = pwm_id * 3;
> +
> +       /*
> +        * TODO(sjg): Use this as a countdown timer for now. We count down
> +        * from the maximum value to 0, then reset.
> +        */
> +       timer_rate_hz = -1;
>         writel(timer_rate_hz, &pwm->tcntb0 + offset);
>
>         val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id));
> diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
> index e78c716..c48a297 100644
> --- a/arch/arm/cpu/armv7/s5p-common/timer.c
> +++ b/arch/arm/cpu/armv7/s5p-common/timer.c
> @@ -39,13 +39,33 @@ static inline struct s5p_timer *s5p_get_base_timer(void)
>         return (struct s5p_timer *)samsung_get_base_timer();
>  }
>
> +/**
> + * Read the countdown timer.
> + *
> + * This operates at 1MHz and counts downwards. It will wrap about every
> + * hour (2^32 microseconds).
> + *
> + * @return current value of timer
> + */
> +static unsigned long timer_get_us_down(void)
> +{
> +       struct s5p_timer *const timer = s5p_get_base_timer();
> +
> +       return readl(&timer->tcnto4);
> +}
> +
>  int timer_init(void)
>  {
>         /* PWM Timer 4 */
> -       pwm_init(4, MUX_DIV_2, 0);
> +       pwm_init(4, MUX_DIV_4, 0);
>         pwm_config(4, 0, 0);
>         pwm_enable(4);
>
> +       /* Use this as the current monotonic time in us */
> +       gd->arch.timer_reset_value = 0;
> +
> +       /* Use this as the last timer value we saw */
> +       gd->arch.lastinc = timer_get_us_down();
>         reset_timer_masked();
>
>         return 0;
> @@ -56,48 +76,28 @@ int timer_init(void)
>   */
>  unsigned long get_timer(unsigned long base)
>  {
> -       return get_timer_masked() - base;
> +       ulong now = timer_get_us_down();
> +
> +       /*
> +        * Increment the time by the amount elapsed since the last read.
> +        * The timer may have wrapped around, but it makes no difference to
> +        * our arithmetic here.
> +        */
> +       gd->arch.timer_reset_value += gd->arch.lastinc - now;
> +       gd->arch.lastinc = now;
> +
> +       /* Divide by 1000 to convert from us to ms */
> +       return gd->arch.timer_reset_value / 1000 - base;
>  }
>
>  /* delay x useconds */
>  void __udelay(unsigned long usec)
>  {
> -       struct s5p_timer *const timer = s5p_get_base_timer();
> -       unsigned long tmo, tmp, count_value;
> -
> -       count_value = readl(&timer->tcntb4);
> -
> -       if (usec >= 1000) {
> -               /*
> -                * if "big" number, spread normalization
> -                * to seconds
> -                * 1. start to normalize for usec to ticks per sec
> -                * 2. find number of "ticks" to wait to achieve target
> -                * 3. finish normalize.
> -                */
> -               tmo = usec / 1000;
> -               tmo *= (CONFIG_SYS_HZ * count_value);
> -               tmo /= 1000;
> -       } else {
> -               /* else small number, don't kill it prior to HZ multiply */
> -               tmo = usec * CONFIG_SYS_HZ * count_value;
> -               tmo /= (1000 * 1000);
> -       }
> -
> -       /* get current timestamp */
> -       tmp = get_current_tick();
> -
> -       /* if setting this fordward will roll time stamp */
> -       /* reset "advancing" timestamp to 0, set lastinc value */
> -       /* else, set advancing stamp wake up time */
> -       if ((tmo + tmp + 1) < tmp)
> -               reset_timer_masked();
> -       else
> -               tmo += tmp;
> -
> -       /* loop till event */
> -       while (get_current_tick() < tmo)
> -               ;       /* nop */
> +       unsigned long count_value;
> +
> +       count_value = timer_get_us_down();
> +       while ((int)(count_value - timer_get_us_down()) < (int)usec)
> +               ;
>  }
>
>  void reset_timer_masked(void)
> @@ -109,30 +109,6 @@ void reset_timer_masked(void)
>         gd->arch.tbl = 0;
>  }
>
> -unsigned long get_timer_masked(void)
> -{
> -       struct s5p_timer *const timer = s5p_get_base_timer();
> -       unsigned long count_value = readl(&timer->tcntb4);
> -
> -       return get_current_tick() / count_value;
> -}
> -
> -unsigned long get_current_tick(void)
> -{
> -       struct s5p_timer *const timer = s5p_get_base_timer();
> -       unsigned long now = readl(&timer->tcnto4);
> -       unsigned long count_value = readl(&timer->tcntb4);
> -
> -       if (gd->arch.lastinc >= now)
> -               gd->arch.tbl += gd->arch.lastinc - now;
> -       else
> -               gd->arch.tbl += gd->arch.lastinc + count_value - now;
> -
> -       gd->arch.lastinc = now;
> -
> -       return gd->arch.tbl;
> -}
> -
>  /*
>   * This function is derived from PowerPC code (read timebase as long long).
>   * On ARM it just returns the timer value.
> --
> 1.8.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 2/9] Exynos: Add timer_get_us function
  2013-02-27 10:02 ` [U-Boot] [PATCH 2/9] Exynos: Add timer_get_us function Akshay Saraswat
@ 2013-02-28  1:27   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2013-02-28  1:27 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> timer_get_us returns the time in microseconds since a certain reference
> point of history.  However, it does not guarantee to return an accurate
> time after a long period; instead, it wraps around (that is, the
> reference point is reset to some other point of history) after some
> periods. The frequency of wrapping around is about an hour (or 2^32
> microseconds).
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
>
> Signed-off-by: Che-Liang Chiou <clchiou@chromium.org>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>

Acked-by: Simon Glass <sjg@chromium.org>

> ---
>  arch/arm/cpu/armv7/s5p-common/timer.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
> index c48a297..de61405 100644
> --- a/arch/arm/cpu/armv7/s5p-common/timer.c
> +++ b/arch/arm/cpu/armv7/s5p-common/timer.c
> @@ -90,6 +90,21 @@ unsigned long get_timer(unsigned long base)
>         return gd->arch.timer_reset_value / 1000 - base;
>  }
>
> +unsigned long timer_get_us(void)
> +{
> +       static unsigned long base_time_us;
> +
> +       struct s5p_timer *const timer =
> +               (struct s5p_timer *)samsung_get_base_timer();
> +       unsigned long now_downward_us = readl(&timer->tcnto4);
> +
> +       if (!base_time_us)
> +               base_time_us = now_downward_us;
> +
> +       /* Note that this timer counts downward. */
> +       return base_time_us - now_downward_us;
> +}
> +
>  /* delay x useconds */
>  void __udelay(unsigned long usec)
>  {
> --
> 1.8.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 3/9] Exynos: pwm: Fix two bugs in the exynos pwm configuration code
  2013-02-27 10:02 ` [U-Boot] [PATCH 3/9] Exynos: pwm: Fix two bugs in the exynos pwm configuration code Akshay Saraswat
@ 2013-02-28  1:29   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2013-02-28  1:29 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> First, the "div" value was being used incorrectly to compute the frequency of
> the PWM timer. The value passed in is a constant which reflects the value
> that would be found in a configuration register, 0 to 4. That should
> correspond to a scaling factor of 1, 2, 4, 8, or 16, 1 << div, but div + 1 was
> being used instead.
>
> Second, the reset value of the timers were being calculated to give an overall
> frequency, thrown out, and set to a maximum value. This was done so that PWM 4
> could be used as the system clock by counting down from a high value, but it
> was applied indiscriminantly. It should at most be applied only to PWM 4.
>
> This change also takes the opportunity to tidy up the pwm_init function.
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
> Build and boot U-boot with this patch, backlight works properly.
>
> Signed-off-by: Gabe Black <gabeblack@google.com>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>

Acked-by: Simon Glass <sjg@chromium.org>

If you redo this patch, I suggest you remove the TODOs.

> ---
>  arch/arm/cpu/armv7/s5p-common/pwm.c | 24 ++++++++++++++----------
>  1 file changed, 14 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
> index 3147f59..02156d1 100644
> --- a/arch/arm/cpu/armv7/s5p-common/pwm.c
> +++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
> @@ -143,7 +143,7 @@ int pwm_init(int pwm_id, int div, int invert)
>         u32 val;
>         const struct s5p_timer *pwm =
>                         (struct s5p_timer *)samsung_get_base_timer();
> -       unsigned long timer_rate_hz;
> +       unsigned long ticks_per_period;
>         unsigned int offset, prescaler;
>
>         /*
> @@ -167,20 +167,24 @@ int pwm_init(int pwm_id, int div, int invert)
>         val |= (div & 0xf) << MUX_DIV_SHIFT(pwm_id);
>         writel(val, &pwm->tcfg1);
>
> -       timer_rate_hz = get_pwm_clk() / ((prescaler + 1) *
> -                       (div + 1));
> +       if (pwm_id == 4) {
> +               /*
> +                * TODO(sjg): Use this as a countdown timer for now. We count
> +                * down from the maximum value to 0, then reset.
> +                */
> +               ticks_per_period = -1UL;
> +       } else {
> +               const unsigned long pwm_hz = 1000;
> +               unsigned long timer_rate_hz = get_pwm_clk() /
> +                       ((prescaler + 1) * (1 << div));
>
> -       timer_rate_hz = timer_rate_hz / CONFIG_SYS_HZ;
> +               ticks_per_period = timer_rate_hz / pwm_hz;
> +       }
>
>         /* set count value */
>         offset = pwm_id * 3;
>
> -       /*
> -        * TODO(sjg): Use this as a countdown timer for now. We count down
> -        * from the maximum value to 0, then reset.
> -        */
> -       timer_rate_hz = -1;
> -       writel(timer_rate_hz, &pwm->tcntb0 + offset);
> +       writel(ticks_per_period, &pwm->tcntb0 + offset);
>
>         val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id));
>         if (invert && (pwm_id < 4))
> --
> 1.8.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 4/9] Exynos: Avoid a divide by zero by specifying a non-zero period for pwm 4
  2013-02-27 10:02 ` [U-Boot] [PATCH 4/9] Exynos: Avoid a divide by zero by specifying a non-zero period for pwm 4 Akshay Saraswat
@ 2013-02-28  1:29   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2013-02-28  1:29 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> The pwm_config function in the exynos pwm driver divides by its period
> period parameter. A function was calling pwm_config with a 0ns period and a
> 0ns duty cycle. That doesn't actually make any sense physically, and results
> in a divide by zero in the driver. This change changes the paremters to be a
> 100000ns period and duty cycle.
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
> Build and boot U-boot with this patch, backlight works properly.
>
> Signed-off-by: Gabe Black <gabeblack@google.com>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>

Acked-by: Simon Glass <sjg@chromium.org>

> ---
>  arch/arm/cpu/armv7/s5p-common/timer.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
> index de61405..6a0fa58 100644
> --- a/arch/arm/cpu/armv7/s5p-common/timer.c
> +++ b/arch/arm/cpu/armv7/s5p-common/timer.c
> @@ -58,7 +58,7 @@ int timer_init(void)
>  {
>         /* PWM Timer 4 */
>         pwm_init(4, MUX_DIV_4, 0);
> -       pwm_config(4, 0, 0);
> +       pwm_config(4, 100000, 100000);
>         pwm_enable(4);
>
>         /* Use this as the current monotonic time in us */
> --
> 1.8.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 5/9] Exynos: Tidy up the pwm_config function in the exynos pwm driver
  2013-02-27 10:02 ` [U-Boot] [PATCH 5/9] Exynos: Tidy up the pwm_config function in the exynos pwm driver Akshay Saraswat
@ 2013-02-28  1:30   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2013-02-28  1:30 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> Some small fixes in the exynos pwm driver:
>
> 1. NS_IN_HZ is non-sensical since these are not compatible units. This
> constant actually describes the number of nanoseconds in a second. Renamed it
> to NS_IN_SEC. Also dropped the unnecessary parenthesis.
> 2. The variable "period" is not used to hold a period, it's used to hold a
> frequency. Renamed it to "frequency".
> 3. tcmp is an unsigned value, so (tcmp < 0) will never be true and the if
> which checks that condition will never execute. Also, there should be no
> problem if the pwm never switches, so there's no reason to subtract one from
> tcmp and therefore no reason to compare it against zero. Removed both ifs. If
> they weren't removed, tcmp should be a signed value.
> 4. Add a check for a 0 period.
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
> Build and boot U-boot with this patch, backlight works properly.
>
> Signed-off-by: Gabe Black <gabeblack@google.com>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>

Acked-by: Simon Glass <sjg@chromium.org>

> ---
>  arch/arm/cpu/armv7/s5p-common/pwm.c | 22 ++++++----------------
>  1 file changed, 6 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
> index 02156d1..6f401b8 100644
> --- a/arch/arm/cpu/armv7/s5p-common/pwm.c
> +++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
> @@ -70,7 +70,7 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
>         return tin_parent_rate / 16;
>  }
>
> -#define NS_IN_HZ (1000000000UL)
> +#define NS_IN_SEC 1000000000UL
>
>  int pwm_config(int pwm_id, int duty_ns, int period_ns)
>  {
> @@ -79,7 +79,7 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns)
>         unsigned int offset;
>         unsigned long tin_rate;
>         unsigned long tin_ns;
> -       unsigned long period;
> +       unsigned long frequency;
>         unsigned long tcon;
>         unsigned long tcnt;
>         unsigned long tcmp;
> @@ -89,34 +89,24 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns)
>          * fact that anything faster than 1GHz is easily representable
>          * by 32bits.
>          */
> -       if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
> +       if (period_ns > NS_IN_SEC || duty_ns > NS_IN_SEC || period_ns == 0)
>                 return -ERANGE;
>
>         if (duty_ns > period_ns)
>                 return -EINVAL;
>
> -       period = NS_IN_HZ / period_ns;
> +       frequency = NS_IN_SEC / period_ns;
>
>         /* Check to see if we are changing the clock rate of the PWM */
> -       tin_rate = pwm_calc_tin(pwm_id, period);
> +       tin_rate = pwm_calc_tin(pwm_id, frequency);
>
> -       tin_ns = NS_IN_HZ / tin_rate;
> +       tin_ns = NS_IN_SEC / tin_rate;
>         tcnt = period_ns / tin_ns;
>
>         /* Note, counters count down */
>         tcmp = duty_ns / tin_ns;
>         tcmp = tcnt - tcmp;
>
> -       /*
> -        * the pwm hw only checks the compare register after a decrement,
> -        * so the pin never toggles if tcmp = tcnt
> -        */
> -       if (tcmp == tcnt)
> -               tcmp--;
> -
> -       if (tcmp < 0)
> -               tcmp = 0;
> -
>         /* Update the PWM register block. */
>         offset = pwm_id * 3;
>         if (pwm_id < 4) {
> --
> 1.8.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 6/9] Exynos: Add peripherial id for pwm
  2013-02-27 10:02 ` [U-Boot] [PATCH 6/9] Exynos: Add peripherial id for pwm Akshay Saraswat
@ 2013-02-28  1:31   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2013-02-28  1:31 UTC (permalink / raw)
  To: u-boot

Hi Akshay,

On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> Add peripherial id for pwm inorder to support
> generic api to get the clk frequency
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
> Build and boot U-boot with this patch, backlight works properly.
>
> Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
> ---
>  arch/arm/include/asm/arch-exynos/periph.h | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h
> index 89bcdfc..e5aed4b 100644
> --- a/arch/arm/include/asm/arch-exynos/periph.h
> +++ b/arch/arm/include/asm/arch-exynos/periph.h
> @@ -61,6 +61,11 @@ enum periph_id {
>         PERIPH_ID_SPI3,
>         PERIPH_ID_SPI4,
>         PERIPH_ID_SDMMC4,
> +       PERIPH_ID_PWM0,
> +       PERIPH_ID_PWM1,
> +       PERIPH_ID_PWM2,
> +       PERIPH_ID_PWM3,
> +       PERIPH_ID_PWM4,

I don't believe this file is used now.

Regards,
Simon

>
>         PERIPH_ID_COUNT,
>         PERIPH_ID_NONE = -1,
> --
> 1.8.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 7/9] Exynos: clock: Add generic api to get the clk freq
  2013-02-27 10:02 ` [U-Boot] [PATCH 7/9] Exynos: clock: Add generic api to get the clk freq Akshay Saraswat
@ 2013-02-28  1:35   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2013-02-28  1:35 UTC (permalink / raw)
  To: u-boot

Hi Akshay,

On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> Add generic api to get the frequency of the required peripherial. This
> API gets the source clock frequency and returns the required frequency
> by dividing with first and second dividers based on the requirement.
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
> Build and boot U-boot with this patch, backlight works properly.

Please remove the TEST= stuff. patman might do the first line for you
(and will print a warning).

>
> Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
> ---
>  arch/arm/cpu/armv7/exynos/clock.c      | 127 +++++++++++++++++++++++++++++++++
>  arch/arm/include/asm/arch-exynos/clk.h |  27 +++++++
>  2 files changed, 154 insertions(+)
>
> diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
> index 956427c..a7a3066 100644
> --- a/arch/arm/cpu/armv7/exynos/clock.c
> +++ b/arch/arm/cpu/armv7/exynos/clock.c
> @@ -27,6 +27,39 @@
>  #include <asm/arch/clk.h>
>  #include <asm/arch/periph.h>
>
> +/* src_bit div_bit prediv_bit */
> +static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
> +       {0,     0,      -1},
> +       {4,     4,      -1},
> +       {8,     8,      -1},
> +       {12,    12,     -1},
> +       {0,     0,      8},
> +       {4,     16,     24},
> +       {8,     0,      8},
> +       {12,    16,     24},
> +       {-1,    -1,     -1},
> +       {16,    0,      8},
> +       {20,    16,     24},
> +       {24,    0,      8},
> +       {0,     0,      4},
> +       {4,     12,     16},
> +       {-1,    -1,     -1},
> +       {-1,    -1,     -1},
> +       {-1,    24,     0},
> +       {-1,    24,     0},
> +       {-1,    24,     0},
> +       {-1,    24,     0},
> +       {-1,    24,     0},
> +       {-1,    24,     0},
> +       {-1,    24,     0},
> +       {-1,    24,     0},
> +       {24,    0,      -1},
> +       {24,    0,      -1},
> +       {24,    0,      -1},
> +       {24,    0,      -1},
> +       {24,    0,      -1},
> +};
> +
>  /* Epll Clock division values to achive different frequency output */
>  static struct set_epll_con_val exynos5_epll_div[] = {
>         { 192000000, 0, 48, 3, 1, 0 },
> @@ -201,6 +234,100 @@ static unsigned long exynos5_get_pll_clk(int pllreg)
>         return fout;
>  }
>
> +unsigned long exynos5_get_periph_rate(enum periph_id peripheral)
> +{
> +       struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
> +       unsigned long sclk, sub_clk;
> +       unsigned int src, div, sub_div;
> +       struct exynos5_clock *clk =
> +                       (struct exynos5_clock *)samsung_get_base_clock();
> +
> +       switch (peripheral) {
> +       case PERIPH_ID_UART0:
> +       case PERIPH_ID_UART1:
> +       case PERIPH_ID_UART2:
> +       case PERIPH_ID_UART3:
> +               src = readl(&clk->src_peric0);
> +               div = readl(&clk->div_peric0);
> +               break;
> +       case PERIPH_ID_PWM0:
> +       case PERIPH_ID_PWM1:
> +       case PERIPH_ID_PWM2:
> +       case PERIPH_ID_PWM3:
> +       case PERIPH_ID_PWM4:
> +               src = readl(&clk->src_peric0);
> +               div = readl(&clk->div_peric3);
> +               break;
> +       case PERIPH_ID_SPI0:
> +       case PERIPH_ID_SPI1:
> +               src = readl(&clk->src_peric1);
> +               div = readl(&clk->div_peric1);
> +               break;
> +       case PERIPH_ID_SPI2:
> +               src = readl(&clk->src_peric1);
> +               div = readl(&clk->div_peric2);
> +               break;
> +       case PERIPH_ID_SPI3:
> +       case PERIPH_ID_SPI4:
> +               src = readl(&clk->sclk_src_isp);
> +               div = readl(&clk->sclk_div_isp);
> +               break;
> +       case PERIPH_ID_SDMMC0:
> +       case PERIPH_ID_SDMMC1:
> +       case PERIPH_ID_SDMMC2:
> +       case PERIPH_ID_SDMMC3:
> +               src = readl(&clk->src_fsys);
> +               div = readl(&clk->div_fsys1);
> +               break;
> +       case PERIPH_ID_I2C0:
> +       case PERIPH_ID_I2C1:
> +       case PERIPH_ID_I2C2:
> +       case PERIPH_ID_I2C3:
> +       case PERIPH_ID_I2C4:
> +       case PERIPH_ID_I2C5:
> +       case PERIPH_ID_I2C6:
> +       case PERIPH_ID_I2C7:
> +               sclk = exynos5_get_pll_clk(MPLL);
> +               sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) & 0x7) + 1;
> +               div = ((readl(&clk->div_top0) >> bit_info->prediv_bit) & 0x7) + 1;
> +               return (sclk / sub_div) / div;
> +       default:
> +               debug("%s: invalid peripheral %d", __func__, peripheral);
> +               return -1;
> +       };
> +
> +       src = (src >> bit_info->src_bit) & 0xf;
> +       if (src == SRC_MPLL)
> +               sclk = exynos5_get_pll_clk(MPLL);
> +       else if (src == SRC_EPLL)
> +               sclk = exynos5_get_pll_clk(EPLL);
> +       else if (src == SRC_VPLL)
> +               sclk = exynos5_get_pll_clk(VPLL);
> +       else
> +               return 0;
> +
> +       sub_div = (div >> bit_info->div_bit) & 0xf;
> +       sub_clk = sclk / (sub_div + 1);
> +
> +       if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {

Please can you add a comment for what this if() is doing?

> +               div = (div >> bit_info->prediv_bit) & 0xff;
> +               return sub_clk / (div + 1);
> +       }

> +
> +       return sub_clk;
> +}
> +
> +unsigned long clock_get_periph_rate(enum periph_id peripheral)
> +{
> +       if (cpu_is_exynos5())
> +               return exynos5_get_periph_rate(peripheral);
> +       else {
> +               if (proid_is_exynos4412())
> +                       return 0;
> +               return 0;
> +       }
> +}
> +
>  /* exynos4: return ARM clock frequency */
>  static unsigned long exynos4_get_arm_clk(void)
>  {
> diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
> index 1935b0b..b459b16 100644
> --- a/arch/arm/include/asm/arch-exynos/clk.h
> +++ b/arch/arm/include/asm/arch-exynos/clk.h
> @@ -22,6 +22,8 @@
>  #ifndef __ASM_ARM_ARCH_CLK_H_
>  #define __ASM_ARM_ARCH_CLK_H_
>
> +#include <asm/arch/periph.h>
> +
>  #define APLL   0
>  #define MPLL   1
>  #define EPLL   2
> @@ -29,6 +31,22 @@
>  #define VPLL   4
>  #define BPLL   5

Suggest EXYNOS_ prefix on these

>
> +enum pll_src_bit {
> +       SRC_MPLL = 6,
> +       SRC_EPLL,
> +       SRC_VPLL,
> +};
> +
> +/* *
> + * This structure is to store the src bit, div bit and prediv bit
> + * positions of the peripheral clocks of the src and div registers
> + */
> +struct clk_bit_info {
> +       int src_bit;
> +       int div_bit;
> +       int prediv_bit;

Should these perhaps be int8_t ? Can this structure move to the C file?

> +};
> +
>  unsigned long get_pll_clk(int pllreg);
>  unsigned long get_arm_clk(void);
>  unsigned long get_i2c_clk(void);
> @@ -44,4 +62,13 @@ int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq);
>  int set_epll_clk(unsigned long rate);
>  int set_spi_clk(int periph_id, unsigned int rate);
>
> +/**
> + * get the clk frequency of the required peripherial
> + *
> + * @param peripherial  Peripherial id
> + *
> + * @return frequency of the peripherial clk
> + */
> +unsigned long clock_get_periph_rate(enum periph_id peripheral);
> +
>  #endif
> --
> 1.8.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 9/9] Exynos: pwm: Use generic api to get pwm clk freq
  2013-02-27 10:02 ` [U-Boot] [PATCH 9/9] Exynos: pwm: Use generic api to get pwm clk freq Akshay Saraswat
@ 2013-02-28  1:36   ` Simon Glass
  2013-02-28  5:33   ` Rajeshwari Birje
  1 sibling, 0 replies; 19+ messages in thread
From: Simon Glass @ 2013-02-28  1:36 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 27, 2013 at 2:02 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> Use generic api to get the pwm clock frequency
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
> Build and boot U-boot with this patch, backlight works properly.
>
> Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>

Acked-by: Simon Glass <sjg@chromium.org>

> ---
>  arch/arm/cpu/armv7/s5p-common/pwm.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
> index 6f401b8..06e0351 100644
> --- a/arch/arm/cpu/armv7/s5p-common/pwm.c
> +++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
> @@ -28,6 +28,7 @@
>  #include <asm/io.h>
>  #include <asm/arch/pwm.h>
>  #include <asm/arch/clk.h>
> +#include <asm/arch/periph.h>
>
>  int pwm_enable(int pwm_id)
>  {
> @@ -60,7 +61,7 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
>         unsigned long tin_parent_rate;
>         unsigned int div;
>
> -       tin_parent_rate = get_pwm_clk();
> +       tin_parent_rate = clock_get_periph_rate(PERIPH_ID_PWM0);
>
>         for (div = 2; div <= 16; div *= 2) {
>                 if ((tin_parent_rate / (div << 16)) < freq)
> @@ -165,8 +166,8 @@ int pwm_init(int pwm_id, int div, int invert)
>                 ticks_per_period = -1UL;
>         } else {
>                 const unsigned long pwm_hz = 1000;
> -               unsigned long timer_rate_hz = get_pwm_clk() /
> -                       ((prescaler + 1) * (1 << div));
> +               unsigned long timer_rate_hz = clock_get_periph_rate(
> +                       PERIPH_ID_PWM0) / ((prescaler + 1) * (1 << div));
>
>                 ticks_per_period = timer_rate_hz / pwm_hz;
>         }
> --
> 1.8.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [U-Boot] [PATCH 9/9] Exynos: pwm: Use generic api to get pwm clk freq
  2013-02-27 10:02 ` [U-Boot] [PATCH 9/9] Exynos: pwm: Use generic api to get pwm clk freq Akshay Saraswat
  2013-02-28  1:36   ` Simon Glass
@ 2013-02-28  5:33   ` Rajeshwari Birje
  1 sibling, 0 replies; 19+ messages in thread
From: Rajeshwari Birje @ 2013-02-28  5:33 UTC (permalink / raw)
  To: u-boot

Hi Akshay

On Wed, Feb 27, 2013 at 3:32 PM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> Use generic api to get the pwm clock frequency
>
> TEST=sf probe 1:0; time sf read 40008000 0 1000
> Try with different numbers of bytes and see that sane values are obtained
> Build and boot U-boot with this patch, backlight works properly.
>
> Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
> ---
>  arch/arm/cpu/armv7/s5p-common/pwm.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c
> index 6f401b8..06e0351 100644
> --- a/arch/arm/cpu/armv7/s5p-common/pwm.c
> +++ b/arch/arm/cpu/armv7/s5p-common/pwm.c
> @@ -28,6 +28,7 @@
>  #include <asm/io.h>
>  #include <asm/arch/pwm.h>
>  #include <asm/arch/clk.h>
> +#include <asm/arch/periph.h>
>
>  int pwm_enable(int pwm_id)
>  {
> @@ -60,7 +61,7 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
>         unsigned long tin_parent_rate;
>         unsigned int div;
>
> -       tin_parent_rate = get_pwm_clk();
> +       tin_parent_rate = clock_get_periph_rate(PERIPH_ID_PWM0);
Kindly check if it works for other S5P soc as  clock_get_periph_rate
is only defined for EXYNOS5.
>
>         for (div = 2; div <= 16; div *= 2) {
>                 if ((tin_parent_rate / (div << 16)) < freq)
> @@ -165,8 +166,8 @@ int pwm_init(int pwm_id, int div, int invert)
>                 ticks_per_period = -1UL;
>         } else {
>                 const unsigned long pwm_hz = 1000;
> -               unsigned long timer_rate_hz = get_pwm_clk() /
> -                       ((prescaler + 1) * (1 << div));
> +               unsigned long timer_rate_hz = clock_get_periph_rate(
> +                       PERIPH_ID_PWM0) / ((prescaler + 1) * (1 << div));
>
>                 ticks_per_period = timer_rate_hz / pwm_hz;
>         }
> --
> 1.8.0
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot



-- 
Regards,
Rajeshwari Shinde

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2013-02-28  5:33 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-27 10:02 [U-Boot] [PATCH 0/9] Fix and Re-organise PWM Timer Akshay Saraswat
2013-02-27 10:02 ` [U-Boot] [PATCH 1/9] Exynos: Change get_timer() to work correctly Akshay Saraswat
2013-02-28  1:26   ` Simon Glass
2013-02-27 10:02 ` [U-Boot] [PATCH 2/9] Exynos: Add timer_get_us function Akshay Saraswat
2013-02-28  1:27   ` Simon Glass
2013-02-27 10:02 ` [U-Boot] [PATCH 3/9] Exynos: pwm: Fix two bugs in the exynos pwm configuration code Akshay Saraswat
2013-02-28  1:29   ` Simon Glass
2013-02-27 10:02 ` [U-Boot] [PATCH 4/9] Exynos: Avoid a divide by zero by specifying a non-zero period for pwm 4 Akshay Saraswat
2013-02-28  1:29   ` Simon Glass
2013-02-27 10:02 ` [U-Boot] [PATCH 5/9] Exynos: Tidy up the pwm_config function in the exynos pwm driver Akshay Saraswat
2013-02-28  1:30   ` Simon Glass
2013-02-27 10:02 ` [U-Boot] [PATCH 6/9] Exynos: Add peripherial id for pwm Akshay Saraswat
2013-02-28  1:31   ` Simon Glass
2013-02-27 10:02 ` [U-Boot] [PATCH 7/9] Exynos: clock: Add generic api to get the clk freq Akshay Saraswat
2013-02-28  1:35   ` Simon Glass
2013-02-27 10:02 ` [U-Boot] [PATCH 8/9] Exynos: clock: Correct pwm source clk selection Akshay Saraswat
2013-02-27 10:02 ` [U-Boot] [PATCH 9/9] Exynos: pwm: Use generic api to get pwm clk freq Akshay Saraswat
2013-02-28  1:36   ` Simon Glass
2013-02-28  5:33   ` Rajeshwari Birje

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.