All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Boyd <sboyd@codeaurora.org>
To: Mike Turquette <mturquette@linaro.org>
Cc: Saravana Kannan <skannan@codeaurora.org>,
	linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v1 03/14] clk: Add of_clk_match() for device drivers
Date: Mon, 12 Aug 2013 22:48:39 -0700	[thread overview]
Message-ID: <20130813054839.GF14845@codeaurora.org> (raw)
In-Reply-To: <20130812202347.5348.76490@quantum>

On 08/12, Mike Turquette wrote:
> Quoting Stephen Boyd (2013-07-24 17:43:31)
> > In similar fashion as of_regulator_match() add an of_clk_match()
> > function that finds an initializes clock init_data structs from
> > devicetree. Drivers should use this API to find clocks that their
> > device is providing and then iterate over their match table
> > registering the clocks with the init data parsed.
> > 
> > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> 
> Stephen,
> 
> In general I like this approach. Writing real device drivers for clock
> controllers is The Right Way and of_clk_match helps.
> 
> Am I reading this correctly that the base register addresses/offsets for
> the clock nodes still come from C files? For example I still see
> pll8_desc defining reg stuff in drivers/clk/msm/gcc-8960.c.

I think we may be able to put the registers in DT but I don't
know why we need to do that if we're already matching up nodes
with C structs. It also made me want to introduce devm_of_iomap()
which just seemed wrong (if you have a dev struct why can't you
use devm_ioremap()).

> 
> What do you think about fetching this data from DT? My thinking here is
> that the definition of that PLL structure would be in C, as would all of
> the control logic. But any per-clock data whatsoever should live in DTS.
> This means the clock data you supply in the DTS files in patches #9 and
> #10 would have base addresses or offsets per-clock. I think this echoes
> Mark R's concerns as well.
> 
> In the future if new chips have more of that type of PLL it would not
> require changes to your clock driver, only new DTS data for the new
> chip.
> 
> I could have that wrong though, there is a fair amount of indirection in
> this series...

Let's take the PLL example and see if I follow what would be in
DT and what would be in C.

Right now we have

	pll8: pll8 {
		#clock-cells = <0>;
		compatible = "qcom,pll";
		clocks = <&pxo>;
	};

in DT and

	static struct pll_desc pll8_desc = {
		.l_reg = 0x3144,
		.m_reg = 0x3148,
		.n_reg = 0x314c,
		.config_reg = 0x3154,
		.mode_reg = 0x3140,
		.status_reg = 0x3158,
		.status_bit = 16,
	};

in C. Do you want everything to be in DT? Something like:

	pll8: pll8@3140 {
		#clock-cells = <0>;
		compatible = "qcom,pll";
		clocks = <&pxo>;
		reg = <0x3140 0x20>;
	};

and then assume that all those registers are offset from the base
register and that the status bit is 16 (it usually is but not
always)?

The problem I see is this quickly breaks down with more
complicated clocks like the RCGs.

We have

	gsbi5_uart_rcg: gsbi5_uart_rcg {
		#clock-cells = <0>;
		compatible = "qcom,p2-mn16-clock";
		clocks = <&pxo>, <&vpll8>;
	};

in DT and

	static struct freq_tbl clk_tbl_gsbi_uart[] = {
		{  1843200, PLL8, 2,  6, 625 },
		{  3686400, PLL8, 2, 12, 625 },
		{  7372800, PLL8, 2, 24, 625 },
		{ 14745600, PLL8, 2, 48, 625 },
		{ 16000000, PLL8, 4,  1,   6 },
		{ 24000000, PLL8, 4,  1,   4 },
		{ 32000000, PLL8, 4,  1,   3 },
		{ 40000000, PLL8, 1,  5,  48 },
		{ 46400000, PLL8, 1, 29, 240 },
		{ 48000000, PLL8, 4,  1,   2 },
		{ 51200000, PLL8, 1,  2,  15 },
		{ 56000000, PLL8, 1,  7,  48 },
		{ 58982400, PLL8, 1, 96, 625 },
		{ 64000000, PLL8, 2,  1,   3 },
		{ }
	};

	static struct rcg_desc gsbi5_uart_rcg = {
		.ctl_reg = 0x2a54,
		.ns_reg = 0x2a54,
		.md_reg = 0x2a50,
		.ctl_bit = 11,
		.mnctr_en_bit = 8,
		.mnctr_reset_bit = 7,
		.mnctr_mode_shift = 5,
		.pre_div_shift = 3,
		.src_sel_shift = 0,
		.n_val_shift = 16,
		.m_val_shift = 16,
		.parent_map = gcc_pxo_pll8_map,
		.freq_tbl = clk_tbl_gsbi_uart,
	};

in C. It starts to get pretty unwieldy when you put this all in
DT, plus you'll notice that the ns_reg and ctl_reg are the same
here because we've generalized the code to work with different
types of software interfaces (technically this clock has no ctl
register, just an NS and MD register). Our multimedia clock
controllers don't follow any standard base/offset pair and so the
ctl_reg can be a different offset from the md_reg depending on
which clock we're talking about. My initial try at translating
this into DT pretty much just made every struct member into a
property, including the duplicate register, expect for the
frequency table, which could probably also be DT-ified with some
work.

	gsbi5_uart_rcg: gsbi5_uart_rcg@2a54 {
		#clock-cells = <0>;
		compatible = "qcom,p2-mn16-clock";
		clocks = <&pxo>, <&vpll8>;
		reg = <0x2a54 0x4>,
		      <0x2a54 0x4>,
		      <0x2a50 0x4>;
		ctl_bit = <11>;
		mnctr_en_bit = <8>;
		mnctr_reset_bit = <7>;
		mnctr_mode_shift = <5>;
		pre_div_shift = <3>;
		src_sel_shift = <0>;
		n_val_shift = <16>;
		m_val_shift = <16>;
	};

This is great for making the kernel DT-data-driven, but I
couldn't find any other driver that was describing register level
details in DT.

The good news is that newer clock controllers follow a standard
and so we can specify one or two register properties and the type
of clock and we're pretty much done. The software interface
hasn't been randomized like on earlier controllers and bits
within registers are always the same. We still have some clocks
that are just on/off switches though and so we'll have to put
register level details like which bit turns that clock on in DT
(which I believe is not preferred/allowed?). I don't see any way
to avoid that if we want it to be entirely DT driven.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

WARNING: multiple messages have this Message-ID (diff)
From: sboyd@codeaurora.org (Stephen Boyd)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v1 03/14] clk: Add of_clk_match() for device drivers
Date: Mon, 12 Aug 2013 22:48:39 -0700	[thread overview]
Message-ID: <20130813054839.GF14845@codeaurora.org> (raw)
In-Reply-To: <20130812202347.5348.76490@quantum>

On 08/12, Mike Turquette wrote:
> Quoting Stephen Boyd (2013-07-24 17:43:31)
> > In similar fashion as of_regulator_match() add an of_clk_match()
> > function that finds an initializes clock init_data structs from
> > devicetree. Drivers should use this API to find clocks that their
> > device is providing and then iterate over their match table
> > registering the clocks with the init data parsed.
> > 
> > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> 
> Stephen,
> 
> In general I like this approach. Writing real device drivers for clock
> controllers is The Right Way and of_clk_match helps.
> 
> Am I reading this correctly that the base register addresses/offsets for
> the clock nodes still come from C files? For example I still see
> pll8_desc defining reg stuff in drivers/clk/msm/gcc-8960.c.

I think we may be able to put the registers in DT but I don't
know why we need to do that if we're already matching up nodes
with C structs. It also made me want to introduce devm_of_iomap()
which just seemed wrong (if you have a dev struct why can't you
use devm_ioremap()).

> 
> What do you think about fetching this data from DT? My thinking here is
> that the definition of that PLL structure would be in C, as would all of
> the control logic. But any per-clock data whatsoever should live in DTS.
> This means the clock data you supply in the DTS files in patches #9 and
> #10 would have base addresses or offsets per-clock. I think this echoes
> Mark R's concerns as well.
> 
> In the future if new chips have more of that type of PLL it would not
> require changes to your clock driver, only new DTS data for the new
> chip.
> 
> I could have that wrong though, there is a fair amount of indirection in
> this series...

Let's take the PLL example and see if I follow what would be in
DT and what would be in C.

Right now we have

	pll8: pll8 {
		#clock-cells = <0>;
		compatible = "qcom,pll";
		clocks = <&pxo>;
	};

in DT and

	static struct pll_desc pll8_desc = {
		.l_reg = 0x3144,
		.m_reg = 0x3148,
		.n_reg = 0x314c,
		.config_reg = 0x3154,
		.mode_reg = 0x3140,
		.status_reg = 0x3158,
		.status_bit = 16,
	};

in C. Do you want everything to be in DT? Something like:

	pll8: pll8 at 3140 {
		#clock-cells = <0>;
		compatible = "qcom,pll";
		clocks = <&pxo>;
		reg = <0x3140 0x20>;
	};

and then assume that all those registers are offset from the base
register and that the status bit is 16 (it usually is but not
always)?

The problem I see is this quickly breaks down with more
complicated clocks like the RCGs.

We have

	gsbi5_uart_rcg: gsbi5_uart_rcg {
		#clock-cells = <0>;
		compatible = "qcom,p2-mn16-clock";
		clocks = <&pxo>, <&vpll8>;
	};

in DT and

	static struct freq_tbl clk_tbl_gsbi_uart[] = {
		{  1843200, PLL8, 2,  6, 625 },
		{  3686400, PLL8, 2, 12, 625 },
		{  7372800, PLL8, 2, 24, 625 },
		{ 14745600, PLL8, 2, 48, 625 },
		{ 16000000, PLL8, 4,  1,   6 },
		{ 24000000, PLL8, 4,  1,   4 },
		{ 32000000, PLL8, 4,  1,   3 },
		{ 40000000, PLL8, 1,  5,  48 },
		{ 46400000, PLL8, 1, 29, 240 },
		{ 48000000, PLL8, 4,  1,   2 },
		{ 51200000, PLL8, 1,  2,  15 },
		{ 56000000, PLL8, 1,  7,  48 },
		{ 58982400, PLL8, 1, 96, 625 },
		{ 64000000, PLL8, 2,  1,   3 },
		{ }
	};

	static struct rcg_desc gsbi5_uart_rcg = {
		.ctl_reg = 0x2a54,
		.ns_reg = 0x2a54,
		.md_reg = 0x2a50,
		.ctl_bit = 11,
		.mnctr_en_bit = 8,
		.mnctr_reset_bit = 7,
		.mnctr_mode_shift = 5,
		.pre_div_shift = 3,
		.src_sel_shift = 0,
		.n_val_shift = 16,
		.m_val_shift = 16,
		.parent_map = gcc_pxo_pll8_map,
		.freq_tbl = clk_tbl_gsbi_uart,
	};

in C. It starts to get pretty unwieldy when you put this all in
DT, plus you'll notice that the ns_reg and ctl_reg are the same
here because we've generalized the code to work with different
types of software interfaces (technically this clock has no ctl
register, just an NS and MD register). Our multimedia clock
controllers don't follow any standard base/offset pair and so the
ctl_reg can be a different offset from the md_reg depending on
which clock we're talking about. My initial try at translating
this into DT pretty much just made every struct member into a
property, including the duplicate register, expect for the
frequency table, which could probably also be DT-ified with some
work.

	gsbi5_uart_rcg: gsbi5_uart_rcg at 2a54 {
		#clock-cells = <0>;
		compatible = "qcom,p2-mn16-clock";
		clocks = <&pxo>, <&vpll8>;
		reg = <0x2a54 0x4>,
		      <0x2a54 0x4>,
		      <0x2a50 0x4>;
		ctl_bit = <11>;
		mnctr_en_bit = <8>;
		mnctr_reset_bit = <7>;
		mnctr_mode_shift = <5>;
		pre_div_shift = <3>;
		src_sel_shift = <0>;
		n_val_shift = <16>;
		m_val_shift = <16>;
	};

This is great for making the kernel DT-data-driven, but I
couldn't find any other driver that was describing register level
details in DT.

The good news is that newer clock controllers follow a standard
and so we can specify one or two register properties and the type
of clock and we're pretty much done. The software interface
hasn't been randomized like on earlier controllers and bits
within registers are always the same. We still have some clocks
that are just on/off switches though and so we'll have to put
register level details like which bit turns that clock on in DT
(which I believe is not preferred/allowed?). I don't see any way
to avoid that if we want it to be entirely DT driven.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

  reply	other threads:[~2013-08-13  5:48 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-25  0:43 [PATCH v1 00/14] Add support for MSM's mmio clocks Stephen Boyd
2013-07-25  0:43 ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 01/14] clk: fixed-rate: Export clk_fixed_rate_register() Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-08-03  3:32   ` Mike Turquette
2013-08-03  3:32     ` Mike Turquette
2013-07-25  0:43 ` [PATCH v1 02/14] clk: Add of_init_clk_data() to parse common clock bindings Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  8:21   ` Tomasz Figa
2013-07-25  8:21     ` Tomasz Figa
2013-07-25 16:36     ` Stephen Boyd
2013-07-25 16:36       ` Stephen Boyd
2013-08-03  1:06       ` Mike Turquette
2013-08-03  1:06         ` Mike Turquette
2013-07-25  0:43 ` [PATCH v1 03/14] clk: Add of_clk_match() for device drivers Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  8:12   ` Tomasz Figa
2013-07-25  8:12     ` Tomasz Figa
2013-07-25 16:36     ` Stephen Boyd
2013-07-25 16:36       ` Stephen Boyd
2013-08-12 20:23   ` Mike Turquette
2013-08-12 20:23     ` Mike Turquette
2013-08-13  5:48     ` Stephen Boyd [this message]
2013-08-13  5:48       ` Stephen Boyd
2013-08-15  5:02       ` Mike Turquette
2013-08-15  5:02         ` Mike Turquette
2013-08-16  1:31         ` Stephen Boyd
2013-08-16  1:31           ` Stephen Boyd
2013-08-16  3:44           ` Mike Turquette
2013-08-16  3:44             ` Mike Turquette
2013-08-16 16:43         ` Kumar Gala
2013-08-16 16:43           ` Kumar Gala
2013-08-16 17:16           ` Kumar Gala
2013-08-16 17:16             ` Kumar Gala
2013-07-25  0:43 ` [PATCH v1 04/14] clk: Add set_rate_and_parent() op Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  8:26   ` Tomasz Figa
2013-07-25  8:26     ` Tomasz Figa
2013-07-25  8:26     ` Tomasz Figa
2013-07-25 16:45     ` Stephen Boyd
2013-07-25 16:45       ` Stephen Boyd
2013-08-09  5:32       ` Mike Turquette
2013-08-09  5:32         ` Mike Turquette
2013-08-09  9:11   ` James Hogan
2013-08-09  9:11     ` James Hogan
2013-08-09  9:11     ` James Hogan
2013-07-25  0:43 ` [PATCH v1 05/14] clk: msm: Add support for phase locked loops (PLLs) Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  8:29   ` Tomasz Figa
2013-07-25  8:29     ` Tomasz Figa
2013-07-25 16:37     ` Stephen Boyd
2013-07-25 16:37       ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 06/14] clk: msm: Add support for root clock generators (RCGs) Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 07/14] clk: msm: Add support for branches/gate clocks Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 08/14] clk: msm: Add MSM clock driver Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  8:32   ` Tomasz Figa
2013-07-25  8:32     ` Tomasz Figa
2013-07-25 16:40     ` Stephen Boyd
2013-07-25 16:40       ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 09/14] clk: msm: Add support for MSM8960's global clock controller (GCC) Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-08-08 17:00   ` Mark Rutland
2013-08-08 17:00     ` Mark Rutland
2013-08-08 17:00     ` Mark Rutland
2013-08-13  5:03     ` Stephen Boyd
2013-08-13  5:03       ` Stephen Boyd
2013-08-13  5:03       ` Stephen Boyd
2013-08-13 14:24       ` Mike Turquette
2013-08-13 14:24         ` Mike Turquette
2013-08-13 14:24         ` Mike Turquette
2013-08-13 18:42         ` Stephen Boyd
2013-08-13 18:42           ` Stephen Boyd
2013-08-13 18:42           ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 10/14] clk: msm: Add support for MSM8960's multimedia clock controller (MMCC) Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-08-08 17:02   ` Mark Rutland
2013-08-08 17:02     ` Mark Rutland
2013-08-08 17:02     ` Mark Rutland
2013-07-25  0:43 ` [PATCH v1 11/14] ARM: dts: msm: Add MSM8960 GCC DT nodes Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 12/14] ARM: dts: msm: Add MSM8960 MMCC " Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 13/14] clk: msm: Add MSM8974 GCC data Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd
2013-07-25  0:43 ` [PATCH v1 14/14] ARM: dts: msm: Add clock entries for MSM8960 uart device Stephen Boyd
2013-07-25  0:43   ` Stephen Boyd

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=20130813054839.GF14845@codeaurora.org \
    --to=sboyd@codeaurora.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mturquette@linaro.org \
    --cc=skannan@codeaurora.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.