All of lore.kernel.org
 help / color / mirror / Atom feed
From: skannan@codeaurora.org (Saravana Kannan)
To: linux-arm-kernel@lists.infradead.org
Subject: Common clock and dvfs
Date: Fri, 22 Apr 2011 18:21:26 -0700	[thread overview]
Message-ID: <4DB22996.8020109@codeaurora.org> (raw)
In-Reply-To: <alpine.LFD.2.02.1104222039330.3323@ionos>

On 04/22/2011 12:37 PM, Thomas Gleixner wrote:
> On Fri, 22 Apr 2011, Colin Cross wrote:
>
>> Is the clock api the right place to do dvfs, or should the clock api
>> be kept simple, and more complicated operations like dvfs be kept
>> outside?
>
> I think it's an orthogonal issue which can be solved once we have
> generic implementations in place for clk_ functions which result in
> DFVS relevant changes.
>
> clk_prepare()
> {
> 	lock_tree();
> 	if (dvfs_validate())
> 		return -ECRAP;
> 	prepare();
> 	unlock_tree();
> }
>
> clk_unprepare()
> {
> 	lock_tree();
> 	unprepare();
> 	dvfs_recalc();
> 	unlock_tree();
> }
>
> clk_set_rate()
> {
> 	lock_tree();
>
> 	if (rate>  clk->rate&&  dvfs_prevalidate(rate))
> 		return -ECRAP;
>
> 	set_and_propagate_rate();
>
> 	if (rate<  old->rate)
> 	   dvfs_recalc();
>
> 	unlock_tree();
> }

I understand that this is just some example code, but I'm not sure how 
accurate you were trying to be. So, I will assume the worst.

I really don't like this lock the whole clock tree approach for DVFS. I 
think a better approach would be something like this:

struct dvfs_tuple {
	long	max_rate; /* Max rate for this DVFS level. */
	int	dvfs_level;
};

/* Yeah, bad name. pick what you like. */
struct dvfs_class {
	int 	*level_cnt;
	int 	num_levels;
	int (*dvfs_update) (int level);
	mutex	lock;
}

stuct clk {
	...
	/* Last entry would have {LONG_MAX, highest level in dvfs}, */
	struct	dvfs_tuple *dvfs_list;
	struct  dvfs_class *dvfs_class;
}

Then

clk_prepare() {
	for each dvfs tuple {
		if current_rate <= max_rate; {
			level = dvfs_level;
			break;
		}
	}

	lock(dvfs_class->mutex);

	clk->dvfs_class->level_cnt[level]++;
	/* Find highest level in this dvfs class with non-zero count */
	if(clk->dvfs_class->update(highest_level))
		return -ECRAP;
	/* Yes, I see locking err, but you get the point */
	unlock(dvfs_class->mutex);
	
	clk->ops->prepare(clk);
}

I did some crappy factorization of functions, returning -ECRAP without 
unlocking, etc, but you get the point.

Whether the "level" translates to controlling power supply A or B or A & 
B is upto the implementation of dvfs_class->dvfs_update() which is per 
SOC/mach/arch.

This will keep the dvfs data structure common for all clocks, remove the 
need to traverse the entire tree and keep the generic code agnostic of 
1-1 vs. many-1 vs many-many.

> We can put the dvfs functions into the propagation code as well and
> back out there when dvfs tells us. That probably works nicely for
> prepare and unprepare, but might be complex for set_rate in the actual
> set_rate propagation (except when the rate is less than the original
> one).

For set rate, you lock the dvfs class, increment the count for the new 
rate's dvfs_level, decrement it for the previous dvfs level, and then 
call dvfs_update() with the max level in that class, unlock dvfs_class.

Thanks,
Saravana

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

  reply	other threads:[~2011-04-23  1:21 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-22 18:15 Common clock and dvfs Colin Cross
2011-04-22 19:37 ` Thomas Gleixner
2011-04-23  1:21   ` Saravana Kannan [this message]
2011-04-23  1:35     ` Saravana Kannan
2011-04-23 13:14     ` Thomas Gleixner
2011-04-22 19:40 ` Mark Brown
2011-04-22 19:48   ` Colin Cross
2011-04-22 20:35     ` Mark Brown
2011-04-22 21:18       ` Colin Cross
2011-04-25 11:03         ` Mark Brown
2011-04-25  8:33 ` Paul Walmsley
2011-04-25 18:26   ` Turquette, Mike
     [not found] <4DC07F10.6010305@ti.com>
2011-05-05  5:08 ` Cousson, Benoit
2011-05-05  5:08   ` Cousson, Benoit
2011-05-05  6:11   ` Colin Cross
2011-05-05  6:11     ` Colin Cross
2011-05-05  6:35     ` Paul Walmsley
2011-05-05  6:35       ` Paul Walmsley
2011-05-05  6:50       ` Colin Cross
2011-05-05  6:50         ` Colin Cross
2011-05-05 13:59         ` Mark Brown
2011-05-05 13:59           ` Mark Brown
2011-05-05 21:08     ` Cousson, Benoit
2011-05-05 21:08       ` Cousson, Benoit
2011-05-05 23:15       ` Colin Cross
2011-05-05 23:15         ` Colin Cross
2011-05-06 17:36         ` Paul Walmsley
2011-05-06 17:36           ` Paul Walmsley
2011-05-06  8:13       ` MyungJoo Ham
2011-05-06  8:13         ` MyungJoo Ham
2011-05-05  6:25   ` Paul Walmsley
2011-05-05  6:25     ` Paul Walmsley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4DB22996.8020109@codeaurora.org \
    --to=skannan@codeaurora.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.