[6/8] clk: tegra30: add 2d and 3d idle clocks
diff mbox series

Message ID 20180720134532.13148-7-ben.dooks@codethink.co.uk
State Changes Requested
Headers show
Series
  • [1/8] clk: tegra: implement reset status callback
Related show

Commit Message

Ben Dooks July 20, 2018, 1:45 p.m. UTC
The 2D and 3D clocks have an IDLE field in bits 15:8 so add these
clocks by making a 2D and 3D mux, and split the divider into the
standard 2D/3D ones and 2D/3D idle clocks.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 drivers/clk/tegra/clk-id.h              |  4 ++++
 drivers/clk/tegra/clk-tegra-periph.c    | 23 +++++++++++++++++++++--
 drivers/clk/tegra/clk-tegra30.c         |  8 ++++++++
 include/dt-bindings/clock/tegra30-car.h |  7 ++++++-
 4 files changed, 39 insertions(+), 3 deletions(-)

Comments

Dmitry Osipenko July 22, 2018, 11:55 a.m. UTC | #1
On Friday, 20 July 2018 16:45:30 MSK Ben Dooks wrote:
> The 2D and 3D clocks have an IDLE field in bits 15:8 so add these
> clocks by making a 2D and 3D mux, and split the divider into the
> standard 2D/3D ones and 2D/3D idle clocks.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  drivers/clk/tegra/clk-id.h              |  4 ++++
>  drivers/clk/tegra/clk-tegra-periph.c    | 23 +++++++++++++++++++++--
>  drivers/clk/tegra/clk-tegra30.c         |  8 ++++++++
>  include/dt-bindings/clock/tegra30-car.h |  7 ++++++-
>  4 files changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
> index b616e33c5255..0d202a70ce66 100644
> --- a/drivers/clk/tegra/clk-id.h
> +++ b/drivers/clk/tegra/clk-id.h
> @@ -91,8 +91,12 @@ enum clk_id {
>  	tegra_clk_fuse_burn,
>  	tegra_clk_gpu,
>  	tegra_clk_gr2d,
> +	tegra_clk_gr2d_mux,
> +	tegra_clk_gr2d_idle,
>  	tegra_clk_gr2d_8,
>  	tegra_clk_gr3d,
> +	tegra_clk_gr3d_mux,
> +	tegra_clk_gr3d_idle,
>  	tegra_clk_gr3d_8,
>  	tegra_clk_hclk,
>  	tegra_clk_hda,
> diff --git a/drivers/clk/tegra/clk-tegra-periph.c
> b/drivers/clk/tegra/clk-tegra-periph.c index 47e5b1ac1a69..83967dac93f2
> 100644
> --- a/drivers/clk/tegra/clk-tegra-periph.c
> +++ b/drivers/clk/tegra/clk-tegra-periph.c
> @@ -263,6 +263,21 @@
>  		.flags = _flags,					\
>  	}
> 
> +#define GATE_DIV(_name, _parent_name, _offset,				\
> +		 _div_shift, _div_width, _div_frac_width, _div_flags,	\
> +			     _clk_num, _gate_flags,  _clk_id, _flags)	\
> +	{								\
> +		.name = _name,						\
> +		.clk_id = _clk_id,					\
> +		.offset = _offset,					\
> +		.p.parent_name =  _parent_name,				\
> +		.periph = TEGRA_CLK_PERIPH(0, 0, 0,			\
> +					   _div_shift, _div_width,	\
> +					   _div_frac_width, _div_flags, \
> +				_clk_num, _gate_flags, NULL, NULL),	\
> +		.flags = _flags						\
> +	}
> +
>  #define PLLP_BASE 0xa0
>  #define PLLP_MISC 0xac
>  #define PLLP_MISC1 0x680
> @@ -646,8 +661,12 @@ static struct tegra_periph_init_data periph_clks[] = {
>  	MUX("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0, 
tegra_clk_epp),
> MUX("host1x", mux_pllm_pllc_pllp_plla, CLK_SOURCE_HOST1X, 28, 0,
> tegra_clk_host1x), MUX("mpe", mux_pllm_pllc_pllp_plla, CLK_SOURCE_MPE, 60,
> 0, tegra_clk_mpe), -	MUX("2d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D, 
21,
> 0, tegra_clk_gr2d), -	MUX("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 
24,
> 0, tegra_clk_gr3d), +	MUX("2d_mux", mux_pllm_pllc_pllp_plla, 
CLK_SOURCE_2D,
> 0, TEGRA_PERIPH_NO_DIV | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_NO_GATE,
> tegra_clk_gr2d_mux), +	GATE_DIV("2d", "2d_mux", CLK_SOURCE_2D, 0, 8, 1,
> TEGRA_DIVIDER_ROUND_UP,21, 0, tegra_clk_gr2d, 0), +	GATE_DIV("2d_idle",
> "2d_mux", CLK_SOURCE_2D, 8, 8, 1, TEGRA_DIVIDER_ROUND_UP, 0,
> TEGRA_PERIPH_NO_GATE | TEGRA_PERIPH_NO_RESET, tegra_clk_gr2d_idle, 0),
> +	MUX("3d_mux", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 0,
> TEGRA_PERIPH_NO_DIV | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_NO_GATE,
> tegra_clk_gr3d_mux), +	GATE_DIV("3d", "3d_mux", CLK_SOURCE_3D, 0, 8, 1,
> TEGRA_DIVIDER_ROUND_UP, 24, 0, tegra_clk_gr3d, 0), +	GATE_DIV("3d_idle",
> "3d_mux", CLK_SOURCE_3D, 8, 8, 1, TEGRA_DIVIDER_ROUND_UP, 0,
> TEGRA_PERIPH_NO_GATE | TEGRA_PERIPH_NO_RESET, tegra_clk_gr3d_idle, 0),
> INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0,
> tegra_clk_vde_8), INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI,
> 20, 0, tegra_clk_vi_8), INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla_pllc4,
> CLK_SOURCE_VI, 20, 0, tegra_clk_vi_9), diff --git
> a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index
> acfe661b2ae7..227d3643ecca 100644
> --- a/drivers/clk/tegra/clk-tegra30.c
> +++ b/drivers/clk/tegra/clk-tegra30.c
> @@ -658,8 +658,12 @@ static struct tegra_devclk devclks[] __initdata = {
>  	{ .dev_id = "mpe", .dt_id = TEGRA30_CLK_MPE },
>  	{ .dev_id = "host1x", .dt_id = TEGRA30_CLK_HOST1X },
>  	{ .dev_id = "3d", .dt_id = TEGRA30_CLK_GR3D },
> +	{ .dev_id = "3d", .con_id = "mux", .dt_id = TEGRA30_CLK_GR3D_MUX },
> +	{ .dev_id = "3d", .con_id = "idle", .dt_id = TEGRA30_CLK_GR3D_IDLE },
>  	{ .dev_id = "3d2", .dt_id = TEGRA30_CLK_GR3D2 },
>  	{ .dev_id = "2d", .dt_id = TEGRA30_CLK_GR2D },
> +	{ .dev_id = "2d", .con_id = "mux", .dt_id = TEGRA30_CLK_GR2D_MUX },
> +	{ .dev_id = "2d", .con_id = "idle", .dt_id = TEGRA30_CLK_GR2D_IDLE },
>  	{ .dev_id = "se", .dt_id = TEGRA30_CLK_SE },
>  	{ .dev_id = "mselect", .dt_id = TEGRA30_CLK_MSELECT },
>  	{ .dev_id = "tegra-nor", .dt_id = TEGRA30_CLK_NOR },
> @@ -762,6 +766,10 @@ static struct tegra_clk tegra30_clks[tegra_clk_max]
> __initdata = { [tegra_clk_host1x] = { .dt_id = TEGRA30_CLK_HOST1X, .present
> = true }, [tegra_clk_gr2d] = { .dt_id = TEGRA30_CLK_GR2D, .present = true
> }, [tegra_clk_gr3d] = { .dt_id = TEGRA30_CLK_GR3D, .present = true },
> +	[tegra_clk_gr2d_mux] = { .dt_id = TEGRA30_CLK_GR2D_MUX, .present = true
> }, +	[tegra_clk_gr3d_mux] = { .dt_id = TEGRA30_CLK_GR3D_MUX, .present =
> true }, +	[tegra_clk_gr2d_idle] = { .dt_id = TEGRA30_CLK_GR2D_IDLE,
> .present = true }, +	[tegra_clk_gr3d_idle] = { .dt_id =
> TEGRA30_CLK_GR3D_IDLE, .present = true }, [tegra_clk_mselect] = { .dt_id =
> TEGRA30_CLK_MSELECT, .present = true }, [tegra_clk_nor] = { .dt_id =
> TEGRA30_CLK_NOR, .present = true }, [tegra_clk_sdmmc1] = { .dt_id =
> TEGRA30_CLK_SDMMC1, .present = true }, diff --git

According to TRM, Tegra20 and Tegra114 have these "idle-mode" clock dividers 
as well. Why only T30 should have them?

> a/include/dt-bindings/clock/tegra30-car.h
> b/include/dt-bindings/clock/tegra30-car.h index 3c90f1535551..eda4ca60351e
> 100644
> --- a/include/dt-bindings/clock/tegra30-car.h
> +++ b/include/dt-bindings/clock/tegra30-car.h
> @@ -269,6 +269,11 @@
>  #define TEGRA30_CLK_AUDIO3_MUX 306
>  #define TEGRA30_CLK_AUDIO4_MUX 307
>  #define TEGRA30_CLK_SPDIF_MUX 308
> -#define TEGRA30_CLK_CLK_MAX 309
> +
> +#define TEGRA30_CLK_GR2D_MUX	309
> +#define TEGRA30_CLK_GR3D_MUX	310
> +#define TEGRA30_CLK_GR2D_IDLE	311
> +#define TEGRA30_CLK_GR3D_IDLE	312
> +#define TEGRA30_CLK_CLK_MAX 313
> 
>  #endif	/* _DT_BINDINGS_CLOCK_TEGRA30_CAR_H */

IIUC, that "idle-mode" divisor is just some kind of power-safe feature, is 
there any real use-case for these clocks? Why not to just pre-configure the 
"idle-mode" bits during the clocks initialization?



--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ben Dooks July 23, 2018, 8:28 a.m. UTC | #2
On 2018-07-22 12:55, Dmitry Osipenko wrote:
> On Friday, 20 July 2018 16:45:30 MSK Ben Dooks wrote:
>> The 2D and 3D clocks have an IDLE field in bits 15:8 so add these
>> clocks by making a 2D and 3D mux, and split the divider into the
>> standard 2D/3D ones and 2D/3D idle clocks.
>> 
>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>

[snip]

> 
> According to TRM, Tegra20 and Tegra114 have these "idle-mode" clock 
> dividers
> as well. Why only T30 should have them?

I've got a separate series to sort t20 bits out, i've not used the 
tegra114

>> a/include/dt-bindings/clock/tegra30-car.h
>> b/include/dt-bindings/clock/tegra30-car.h index 
>> 3c90f1535551..eda4ca60351e
>> 100644
>> --- a/include/dt-bindings/clock/tegra30-car.h
>> +++ b/include/dt-bindings/clock/tegra30-car.h
>> @@ -269,6 +269,11 @@
>>  #define TEGRA30_CLK_AUDIO3_MUX 306
>>  #define TEGRA30_CLK_AUDIO4_MUX 307
>>  #define TEGRA30_CLK_SPDIF_MUX 308
>> -#define TEGRA30_CLK_CLK_MAX 309
>> +
>> +#define TEGRA30_CLK_GR2D_MUX	309
>> +#define TEGRA30_CLK_GR3D_MUX	310
>> +#define TEGRA30_CLK_GR2D_IDLE	311
>> +#define TEGRA30_CLK_GR3D_IDLE	312
>> +#define TEGRA30_CLK_CLK_MAX 313
>> 
>>  #endif	/* _DT_BINDINGS_CLOCK_TEGRA30_CAR_H */
> 
> IIUC, that "idle-mode" divisor is just some kind of power-safe feature, 
> is
> there any real use-case for these clocks? Why not to just pre-configure 
> the
> "idle-mode" bits during the clocks initialization?

It is is nice to have it available after to check, other than that we're 
not
using any drivers that currently dynamically change the values of this.

--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Osipenko July 23, 2018, 11:33 a.m. UTC | #3
On Monday, 23 July 2018 11:28:25 MSK Ben Dooks wrote:
> On 2018-07-22 12:55, Dmitry Osipenko wrote:
> > On Friday, 20 July 2018 16:45:30 MSK Ben Dooks wrote:
> >> The 2D and 3D clocks have an IDLE field in bits 15:8 so add these
> >> clocks by making a 2D and 3D mux, and split the divider into the
> >> standard 2D/3D ones and 2D/3D idle clocks.
> >> 
> >> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> 
> [snip]

> @@ -658,8 +658,12 @@ static struct tegra_devclk devclks[] __initdata = {
>  	{ .dev_id = "mpe", .dt_id = TEGRA30_CLK_MPE },
>  	{ .dev_id = "host1x", .dt_id = TEGRA30_CLK_HOST1X },
>  	{ .dev_id = "3d", .dt_id = TEGRA30_CLK_GR3D },
> +	{ .dev_id = "3d", .con_id = "mux", .dt_id = TEGRA30_CLK_GR3D_MUX },
> +	{ .dev_id = "3d", .con_id = "idle", .dt_id = TEGRA30_CLK_GR3D_IDLE },
>  	{ .dev_id = "3d2", .dt_id = TEGRA30_CLK_GR3D2 },

The  "3d2" also has the "idle" divisor, why have you skipped it?

>  	{ .dev_id = "2d", .dt_id = TEGRA30_CLK_GR2D },
> +	{ .dev_id = "2d", .con_id = "mux", .dt_id = TEGRA30_CLK_GR2D_MUX },
> +	{ .dev_id = "2d", .con_id = "idle", .dt_id = TEGRA30_CLK_GR2D_IDLE },
>  	{ .dev_id = "se", .dt_id = TEGRA30_CLK_SE },
>  	{ .dev_id = "mselect", .dt_id = TEGRA30_CLK_MSELECT },
>  	{ .dev_id = "tegra-nor", .dt_id = TEGRA30_CLK_NOR },

[snip]

> 
> > According to TRM, Tegra20 and Tegra114 have these "idle-mode" clock
> > dividers
> > as well. Why only T30 should have them?
> 
> I've got a separate series to sort t20 bits out, i've not used the
> tegra114
> 

This makes this series to look a bit inconsistent, please send out all the 
patches to give a consistent view.

I don't see anything that could really stop you from adding the clocks for 
T114, its 2d/3d clocks definition pretty matches to T20/30.

> >> a/include/dt-bindings/clock/tegra30-car.h
> >> b/include/dt-bindings/clock/tegra30-car.h index
> >> 3c90f1535551..eda4ca60351e
> >> 100644
> >> --- a/include/dt-bindings/clock/tegra30-car.h
> >> +++ b/include/dt-bindings/clock/tegra30-car.h
> >> @@ -269,6 +269,11 @@
> >> 
> >>  #define TEGRA30_CLK_AUDIO3_MUX 306
> >>  #define TEGRA30_CLK_AUDIO4_MUX 307
> >>  #define TEGRA30_CLK_SPDIF_MUX 308
> >> 
> >> -#define TEGRA30_CLK_CLK_MAX 309
> >> +
> >> +#define TEGRA30_CLK_GR2D_MUX	309
> >> +#define TEGRA30_CLK_GR3D_MUX	310
> >> +#define TEGRA30_CLK_GR2D_IDLE	311
> >> +#define TEGRA30_CLK_GR3D_IDLE	312
> >> +#define TEGRA30_CLK_CLK_MAX 313
> >> 
> >>  #endif	/* _DT_BINDINGS_CLOCK_TEGRA30_CAR_H */
> > 
> > IIUC, that "idle-mode" divisor is just some kind of power-safe feature,
> > is
> > there any real use-case for these clocks? Why not to just pre-configure
> > the
> > "idle-mode" bits during the clocks initialization?
> 
> It is is nice to have it available after to check,

Please initialize the "idle" clock rate via the tegra_clk_init_table in the 
patch that adds the clock or in a followup patch within the same patchset.

> other than that we're
> not
> using any drivers that currently dynamically change the values of this.

All changes made to upstream kernel must be justified, the only acceptable 
justification is that a change is required for the upstream driver.



--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ben Dooks July 23, 2018, 11:37 a.m. UTC | #4
On 2018-07-23 12:33, Dmitry Osipenko wrote:
> On Monday, 23 July 2018 11:28:25 MSK Ben Dooks wrote:
>> On 2018-07-22 12:55, Dmitry Osipenko wrote:
>> > On Friday, 20 July 2018 16:45:30 MSK Ben Dooks wrote:
>> >> The 2D and 3D clocks have an IDLE field in bits 15:8 so add these
>> >> clocks by making a 2D and 3D mux, and split the divider into the
>> >> standard 2D/3D ones and 2D/3D idle clocks.
>> >>
>> >> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>> 
>> [snip]
> 
>> @@ -658,8 +658,12 @@ static struct tegra_devclk devclks[] __initdata = 
>> {
>>  	{ .dev_id = "mpe", .dt_id = TEGRA30_CLK_MPE },
>>  	{ .dev_id = "host1x", .dt_id = TEGRA30_CLK_HOST1X },
>>  	{ .dev_id = "3d", .dt_id = TEGRA30_CLK_GR3D },
>> +	{ .dev_id = "3d", .con_id = "mux", .dt_id = TEGRA30_CLK_GR3D_MUX },
>> +	{ .dev_id = "3d", .con_id = "idle", .dt_id = TEGRA30_CLK_GR3D_IDLE 
>> },
>>  	{ .dev_id = "3d2", .dt_id = TEGRA30_CLK_GR3D2 },
> 
> The  "3d2" also has the "idle" divisor, why have you skipped it?

Thanks, missed this.

>>  	{ .dev_id = "2d", .dt_id = TEGRA30_CLK_GR2D },
>> +	{ .dev_id = "2d", .con_id = "mux", .dt_id = TEGRA30_CLK_GR2D_MUX },
>> +	{ .dev_id = "2d", .con_id = "idle", .dt_id = TEGRA30_CLK_GR2D_IDLE 
>> },
>>  	{ .dev_id = "se", .dt_id = TEGRA30_CLK_SE },
>>  	{ .dev_id = "mselect", .dt_id = TEGRA30_CLK_MSELECT },
>>  	{ .dev_id = "tegra-nor", .dt_id = TEGRA30_CLK_NOR },
> 
> [snip]
> 
>> 
>> > According to TRM, Tegra20 and Tegra114 have these "idle-mode" clock
>> > dividers
>> > as well. Why only T30 should have them?
>> 
>> I've got a separate series to sort t20 bits out, i've not used the
>> tegra114
>> 
> 
> This makes this series to look a bit inconsistent, please send out all 
> the
> patches to give a consistent view.
> 
> I don't see anything that could really stop you from adding the clocks 
> for
> T114, its 2d/3d clocks definition pretty matches to T20/30.

I'd prefer not to be touch architectures I don't have access to do.

> >> a/include/dt-bindings/clock/tegra30-car.h
>> >> b/include/dt-bindings/clock/tegra30-car.h index
>> >> 3c90f1535551..eda4ca60351e
>> >> 100644
>> >> --- a/include/dt-bindings/clock/tegra30-car.h
>> >> +++ b/include/dt-bindings/clock/tegra30-car.h
>> >> @@ -269,6 +269,11 @@
>> >>
>> >>  #define TEGRA30_CLK_AUDIO3_MUX 306
>> >>  #define TEGRA30_CLK_AUDIO4_MUX 307
>> >>  #define TEGRA30_CLK_SPDIF_MUX 308
>> >>
>> >> -#define TEGRA30_CLK_CLK_MAX 309
>> >> +
>> >> +#define TEGRA30_CLK_GR2D_MUX	309
>> >> +#define TEGRA30_CLK_GR3D_MUX	310
>> >> +#define TEGRA30_CLK_GR2D_IDLE	311
>> >> +#define TEGRA30_CLK_GR3D_IDLE	312
>> >> +#define TEGRA30_CLK_CLK_MAX 313
>> >>
>> >>  #endif	/* _DT_BINDINGS_CLOCK_TEGRA30_CAR_H */
>> >
>> > IIUC, that "idle-mode" divisor is just some kind of power-safe feature,
>> > is
>> > there any real use-case for these clocks? Why not to just pre-configure
>> > the
>> > "idle-mode" bits during the clocks initialization?
>> 
>> It is is nice to have it available after to check,
> 
> Please initialize the "idle" clock rate via the tegra_clk_init_table in 
> the
> patch that adds the clock or in a followup patch within the same 
> patchset.
> 
>> other than that we're
>> not
>> using any drivers that currently dynamically change the values of 
>> this.
> 
> All changes made to upstream kernel must be justified, the only 
> acceptable
> justification is that a change is required for the upstream driver.
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Osipenko July 23, 2018, 1:05 p.m. UTC | #5
On Friday, 20 July 2018 16:45:30 MSK Ben Dooks wrote:
> The 2D and 3D clocks have an IDLE field in bits 15:8 so add these
> clocks by making a 2D and 3D mux, and split the divider into the
> standard 2D/3D ones and 2D/3D idle clocks.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  drivers/clk/tegra/clk-id.h              |  4 ++++
>  drivers/clk/tegra/clk-tegra-periph.c    | 23 +++++++++++++++++++++--
>  drivers/clk/tegra/clk-tegra30.c         |  8 ++++++++
>  include/dt-bindings/clock/tegra30-car.h |  7 ++++++-
>  4 files changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
> index b616e33c5255..0d202a70ce66 100644
> --- a/drivers/clk/tegra/clk-id.h
> +++ b/drivers/clk/tegra/clk-id.h
> @@ -91,8 +91,12 @@ enum clk_id {
>  	tegra_clk_fuse_burn,
>  	tegra_clk_gpu,
>  	tegra_clk_gr2d,
> +	tegra_clk_gr2d_mux,
> +	tegra_clk_gr2d_idle,
>  	tegra_clk_gr2d_8,
>  	tegra_clk_gr3d,
> +	tegra_clk_gr3d_mux,
> +	tegra_clk_gr3d_idle,
>  	tegra_clk_gr3d_8,
>  	tegra_clk_hclk,
>  	tegra_clk_hda,
> diff --git a/drivers/clk/tegra/clk-tegra-periph.c
> b/drivers/clk/tegra/clk-tegra-periph.c index 47e5b1ac1a69..83967dac93f2
> 100644
> --- a/drivers/clk/tegra/clk-tegra-periph.c
> +++ b/drivers/clk/tegra/clk-tegra-periph.c
> @@ -263,6 +263,21 @@
>  		.flags = _flags,					\
>  	}
> 
> +#define GATE_DIV(_name, _parent_name, _offset,				\
> +		 _div_shift, _div_width, _div_frac_width, _div_flags,	\
> +			     _clk_num, _gate_flags,  _clk_id, _flags)	\
> +	{								\
> +		.name = _name,						\
> +		.clk_id = _clk_id,					\
> +		.offset = _offset,					\
> +		.p.parent_name =  _parent_name,				\
> +		.periph = TEGRA_CLK_PERIPH(0, 0, 0,			\
> +					   _div_shift, _div_width,	\
> +					   _div_frac_width, _div_flags, \
> +				_clk_num, _gate_flags, NULL, NULL),	\
> +		.flags = _flags						\
> +	}
> +
>  #define PLLP_BASE 0xa0
>  #define PLLP_MISC 0xac
>  #define PLLP_MISC1 0x680
> @@ -646,8 +661,12 @@ static struct tegra_periph_init_data periph_clks[] = {
>  	MUX("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0, 
tegra_clk_epp),
> MUX("host1x", mux_pllm_pllc_pllp_plla, CLK_SOURCE_HOST1X, 28, 0,
> tegra_clk_host1x), MUX("mpe", mux_pllm_pllc_pllp_plla, CLK_SOURCE_MPE, 60,
> 0, tegra_clk_mpe), -	MUX("2d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D, 
21,
> 0, tegra_clk_gr2d), -	MUX("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 
24,
> 0, tegra_clk_gr3d), +	MUX("2d_mux", mux_pllm_pllc_pllp_plla, 
CLK_SOURCE_2D,
> 0, TEGRA_PERIPH_NO_DIV | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_NO_GATE,
> tegra_clk_gr2d_mux), +	GATE_DIV("2d", "2d_mux", CLK_SOURCE_2D, 0, 8, 1,
> TEGRA_DIVIDER_ROUND_UP,21, 0, tegra_clk_gr2d, 0), +	GATE_DIV("2d_idle",
> "2d_mux", CLK_SOURCE_2D, 8, 8, 1, TEGRA_DIVIDER_ROUND_UP, 0,
> TEGRA_PERIPH_NO_GATE | TEGRA_PERIPH_NO_RESET, tegra_clk_gr2d_idle, 0),
> +	MUX("3d_mux", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 0,

Now that the actual parent clock is specified by the "mux" clock, you have to 
adjust the tegra_clk_init_table accordingly.



--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Osipenko July 24, 2018, 11:31 a.m. UTC | #6
On Monday, 23 July 2018 16:05:21 MSK Dmitry Osipenko wrote:
> On Friday, 20 July 2018 16:45:30 MSK Ben Dooks wrote:
> > The 2D and 3D clocks have an IDLE field in bits 15:8 so add these
> > clocks by making a 2D and 3D mux, and split the divider into the
> > standard 2D/3D ones and 2D/3D idle clocks.
> > 
> > Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> > ---
> >  drivers/clk/tegra/clk-id.h              |  4 ++++
> >  drivers/clk/tegra/clk-tegra-periph.c    | 23 +++++++++++++++++++++--
> >  drivers/clk/tegra/clk-tegra30.c         |  8 ++++++++
> >  include/dt-bindings/clock/tegra30-car.h |  7 ++++++-
> >  4 files changed, 39 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
> > index b616e33c5255..0d202a70ce66 100644
> > --- a/drivers/clk/tegra/clk-id.h
> > +++ b/drivers/clk/tegra/clk-id.h
> > @@ -91,8 +91,12 @@ enum clk_id {
> >  	tegra_clk_fuse_burn,
> >  	tegra_clk_gpu,
> >  	tegra_clk_gr2d,
> > +	tegra_clk_gr2d_mux,
> > +	tegra_clk_gr2d_idle,
> >  	tegra_clk_gr2d_8,
> >  	tegra_clk_gr3d,
> > +	tegra_clk_gr3d_mux,
> > +	tegra_clk_gr3d_idle,
> >  	tegra_clk_gr3d_8,
> >  	tegra_clk_hclk,
> >  	tegra_clk_hda,
> > diff --git a/drivers/clk/tegra/clk-tegra-periph.c
> > b/drivers/clk/tegra/clk-tegra-periph.c index 47e5b1ac1a69..83967dac93f2
> > 100644
> > --- a/drivers/clk/tegra/clk-tegra-periph.c
> > +++ b/drivers/clk/tegra/clk-tegra-periph.c
> > @@ -263,6 +263,21 @@
> >  		.flags = _flags,					\
> >  	}
> > 
> > +#define GATE_DIV(_name, _parent_name, _offset,				\
> > +		 _div_shift, _div_width, _div_frac_width, _div_flags,	\
> > +			     _clk_num, _gate_flags,  _clk_id, _flags)	\
> > +	{								\
> > +		.name = _name,						\
> > +		.clk_id = _clk_id,					\
> > +		.offset = _offset,					\
> > +		.p.parent_name =  _parent_name,				\
> > +		.periph = TEGRA_CLK_PERIPH(0, 0, 0,			\
> > +					   _div_shift, _div_width,	\
> > +					   _div_frac_width, _div_flags, \
> > +				_clk_num, _gate_flags, NULL, NULL),	\
> > +		.flags = _flags						\
> > +	}
> > +
> >  #define PLLP_BASE 0xa0
> >  #define PLLP_MISC 0xac
> >  #define PLLP_MISC1 0x680
> > @@ -646,8 +661,12 @@ static struct tegra_periph_init_data periph_clks[] = {
> >  	MUX("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0, 
> tegra_clk_epp),
> > MUX("host1x", mux_pllm_pllc_pllp_plla, CLK_SOURCE_HOST1X, 28, 0,
> > tegra_clk_host1x), MUX("mpe", mux_pllm_pllc_pllp_plla, CLK_SOURCE_MPE, 60,
> > 0, tegra_clk_mpe), -	MUX("2d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D, 
> 21,
> > 0, tegra_clk_gr2d), -	MUX("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 
> 24,
> > 0, tegra_clk_gr3d), +	MUX("2d_mux", mux_pllm_pllc_pllp_plla, 
> CLK_SOURCE_2D,
> > 0, TEGRA_PERIPH_NO_DIV | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_NO_GATE,
> > tegra_clk_gr2d_mux), +	GATE_DIV("2d", "2d_mux", CLK_SOURCE_2D, 0, 8, 1,
> > TEGRA_DIVIDER_ROUND_UP,21, 0, tegra_clk_gr2d, 0), +	GATE_DIV("2d_idle",
> > "2d_mux", CLK_SOURCE_2D, 8, 8, 1, TEGRA_DIVIDER_ROUND_UP, 0,
> > TEGRA_PERIPH_NO_GATE | TEGRA_PERIPH_NO_RESET, tegra_clk_gr2d_idle, 0),
> > +	MUX("3d_mux", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 0,
> 
> Now that the actual parent clock is specified by the "mux" clock, you have to 
> adjust the tegra_clk_init_table accordingly.
> 
> 
> 
> 

The 3d/2d clocks do not have a parent on T20 with these patches being applied.

# cat /sys/kernel/debug/clk/clk_summary 
                                 enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
 clock                                0        0        0       32768          0     0  50000
 3d                                   1        1        0           0          0     0  50000
 2d                                   1        1        0           0          0     0  50000
 clk_32k                              2        2        0       32768          0     0  50000
    blink_override                    1        1        0       32768          0     0  50000
       blink                          2        2        0       32768          0     0  50000
    kbc                               0        0        0       32768          0     0  50000
    rtc                               2        2        0       32768          0     0  50000
...


Same on T30.

# cat /sys/kernel/debug/clk/clk_summary 
                                 enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
...
 3d_idle                              0        0        0           0          0     0  50000
 3d                                   1        1        0           0          0     0  50000
 2d_idle                              0        0        0           0          0     0  50000
 2d                                   1        1        0           0          0     0  50000
 clk_32k                              2        2        0       32768          0     0  50000
    blink_override                    1        1        0       32768          0     0  50000
...



--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ben Dooks July 24, 2018, 12:32 p.m. UTC | #7
On 24/07/18 12:31, Dmitry Osipenko wrote:
> On Monday, 23 July 2018 16:05:21 MSK Dmitry Osipenko wrote:
>> On Friday, 20 July 2018 16:45:30 MSK Ben Dooks wrote:
>>> The 2D and 3D clocks have an IDLE field in bits 15:8 so add these
>>> clocks by making a 2D and 3D mux, and split the divider into the
>>> standard 2D/3D ones and 2D/3D idle clocks.
>>>
>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>> ---
>>>   drivers/clk/tegra/clk-id.h              |  4 ++++
>>>   drivers/clk/tegra/clk-tegra-periph.c    | 23 +++++++++++++++++++++--
>>>   drivers/clk/tegra/clk-tegra30.c         |  8 ++++++++
>>>   include/dt-bindings/clock/tegra30-car.h |  7 ++++++-
>>>   4 files changed, 39 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
>>> index b616e33c5255..0d202a70ce66 100644
>>> --- a/drivers/clk/tegra/clk-id.h
>>> +++ b/drivers/clk/tegra/clk-id.h
>>> @@ -91,8 +91,12 @@ enum clk_id {
>>>   	tegra_clk_fuse_burn,
>>>   	tegra_clk_gpu,
>>>   	tegra_clk_gr2d,
>>> +	tegra_clk_gr2d_mux,
>>> +	tegra_clk_gr2d_idle,
>>>   	tegra_clk_gr2d_8,
>>>   	tegra_clk_gr3d,
>>> +	tegra_clk_gr3d_mux,
>>> +	tegra_clk_gr3d_idle,
>>>   	tegra_clk_gr3d_8,
>>>   	tegra_clk_hclk,
>>>   	tegra_clk_hda,
>>> diff --git a/drivers/clk/tegra/clk-tegra-periph.c
>>> b/drivers/clk/tegra/clk-tegra-periph.c index 47e5b1ac1a69..83967dac93f2
>>> 100644
>>> --- a/drivers/clk/tegra/clk-tegra-periph.c
>>> +++ b/drivers/clk/tegra/clk-tegra-periph.c
>>> @@ -263,6 +263,21 @@
>>>   		.flags = _flags,					\
>>>   	}
>>>
>>> +#define GATE_DIV(_name, _parent_name, _offset,				\
>>> +		 _div_shift, _div_width, _div_frac_width, _div_flags,	\
>>> +			     _clk_num, _gate_flags,  _clk_id, _flags)	\
>>> +	{								\
>>> +		.name = _name,						\
>>> +		.clk_id = _clk_id,					\
>>> +		.offset = _offset,					\
>>> +		.p.parent_name =  _parent_name,				\
>>> +		.periph = TEGRA_CLK_PERIPH(0, 0, 0,			\
>>> +					   _div_shift, _div_width,	\
>>> +					   _div_frac_width, _div_flags, \
>>> +				_clk_num, _gate_flags, NULL, NULL),	\
>>> +		.flags = _flags						\
>>> +	}
>>> +
>>>   #define PLLP_BASE 0xa0
>>>   #define PLLP_MISC 0xac
>>>   #define PLLP_MISC1 0x680
>>> @@ -646,8 +661,12 @@ static struct tegra_periph_init_data periph_clks[] = {
>>>   	MUX("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0,
>> tegra_clk_epp),
>>> MUX("host1x", mux_pllm_pllc_pllp_plla, CLK_SOURCE_HOST1X, 28, 0,
>>> tegra_clk_host1x), MUX("mpe", mux_pllm_pllc_pllp_plla, CLK_SOURCE_MPE, 60,
>>> 0, tegra_clk_mpe), -	MUX("2d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D,
>> 21,
>>> 0, tegra_clk_gr2d), -	MUX("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D,
>> 24,
>>> 0, tegra_clk_gr3d), +	MUX("2d_mux", mux_pllm_pllc_pllp_plla,
>> CLK_SOURCE_2D,
>>> 0, TEGRA_PERIPH_NO_DIV | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_NO_GATE,
>>> tegra_clk_gr2d_mux), +	GATE_DIV("2d", "2d_mux", CLK_SOURCE_2D, 0, 8, 1,
>>> TEGRA_DIVIDER_ROUND_UP,21, 0, tegra_clk_gr2d, 0), +	GATE_DIV("2d_idle",
>>> "2d_mux", CLK_SOURCE_2D, 8, 8, 1, TEGRA_DIVIDER_ROUND_UP, 0,
>>> TEGRA_PERIPH_NO_GATE | TEGRA_PERIPH_NO_RESET, tegra_clk_gr2d_idle, 0),
>>> +	MUX("3d_mux", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 0,
>>
>> Now that the actual parent clock is specified by the "mux" clock, you have to
>> adjust the tegra_clk_init_table accordingly.
>>
>>
>>
>>
> 
> The 3d/2d clocks do not have a parent on T20 with these patches being applied.

Thanks, I need to extract the setup from some of the other changes that
we did for the tegra30a/20a devices.

Patch
diff mbox series

diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
index b616e33c5255..0d202a70ce66 100644
--- a/drivers/clk/tegra/clk-id.h
+++ b/drivers/clk/tegra/clk-id.h
@@ -91,8 +91,12 @@  enum clk_id {
 	tegra_clk_fuse_burn,
 	tegra_clk_gpu,
 	tegra_clk_gr2d,
+	tegra_clk_gr2d_mux,
+	tegra_clk_gr2d_idle,
 	tegra_clk_gr2d_8,
 	tegra_clk_gr3d,
+	tegra_clk_gr3d_mux,
+	tegra_clk_gr3d_idle,
 	tegra_clk_gr3d_8,
 	tegra_clk_hclk,
 	tegra_clk_hda,
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index 47e5b1ac1a69..83967dac93f2 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -263,6 +263,21 @@ 
 		.flags = _flags,					\
 	}
 
+#define GATE_DIV(_name, _parent_name, _offset,				\
+		 _div_shift, _div_width, _div_frac_width, _div_flags,	\
+			     _clk_num, _gate_flags,  _clk_id, _flags)	\
+	{								\
+		.name = _name,						\
+		.clk_id = _clk_id,					\
+		.offset = _offset,					\
+		.p.parent_name =  _parent_name,				\
+		.periph = TEGRA_CLK_PERIPH(0, 0, 0,			\
+					   _div_shift, _div_width,	\
+					   _div_frac_width, _div_flags, \
+				_clk_num, _gate_flags, NULL, NULL),	\
+		.flags = _flags						\
+	}
+
 #define PLLP_BASE 0xa0
 #define PLLP_MISC 0xac
 #define PLLP_MISC1 0x680
@@ -646,8 +661,12 @@  static struct tegra_periph_init_data periph_clks[] = {
 	MUX("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp),
 	MUX("host1x", mux_pllm_pllc_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x),
 	MUX("mpe", mux_pllm_pllc_pllp_plla, CLK_SOURCE_MPE, 60, 0, tegra_clk_mpe),
-	MUX("2d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d),
-	MUX("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d),
+	MUX("2d_mux", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D, 0, TEGRA_PERIPH_NO_DIV | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_NO_GATE, tegra_clk_gr2d_mux),
+	GATE_DIV("2d", "2d_mux", CLK_SOURCE_2D, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,21, 0, tegra_clk_gr2d, 0),
+	GATE_DIV("2d_idle", "2d_mux", CLK_SOURCE_2D, 8, 8, 1, TEGRA_DIVIDER_ROUND_UP, 0, TEGRA_PERIPH_NO_GATE | TEGRA_PERIPH_NO_RESET, tegra_clk_gr2d_idle, 0),
+	MUX("3d_mux", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 0, TEGRA_PERIPH_NO_DIV | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_NO_GATE, tegra_clk_gr3d_mux),
+	GATE_DIV("3d", "3d_mux", CLK_SOURCE_3D, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 24, 0, tegra_clk_gr3d, 0),
+	GATE_DIV("3d_idle", "3d_mux", CLK_SOURCE_3D, 8, 8, 1, TEGRA_DIVIDER_ROUND_UP, 0, TEGRA_PERIPH_NO_GATE | TEGRA_PERIPH_NO_RESET, tegra_clk_gr3d_idle, 0),
 	INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde_8),
 	INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_8),
 	INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla_pllc4, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_9),
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index acfe661b2ae7..227d3643ecca 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -658,8 +658,12 @@  static struct tegra_devclk devclks[] __initdata = {
 	{ .dev_id = "mpe", .dt_id = TEGRA30_CLK_MPE },
 	{ .dev_id = "host1x", .dt_id = TEGRA30_CLK_HOST1X },
 	{ .dev_id = "3d", .dt_id = TEGRA30_CLK_GR3D },
+	{ .dev_id = "3d", .con_id = "mux", .dt_id = TEGRA30_CLK_GR3D_MUX },
+	{ .dev_id = "3d", .con_id = "idle", .dt_id = TEGRA30_CLK_GR3D_IDLE },
 	{ .dev_id = "3d2", .dt_id = TEGRA30_CLK_GR3D2 },
 	{ .dev_id = "2d", .dt_id = TEGRA30_CLK_GR2D },
+	{ .dev_id = "2d", .con_id = "mux", .dt_id = TEGRA30_CLK_GR2D_MUX },
+	{ .dev_id = "2d", .con_id = "idle", .dt_id = TEGRA30_CLK_GR2D_IDLE },
 	{ .dev_id = "se", .dt_id = TEGRA30_CLK_SE },
 	{ .dev_id = "mselect", .dt_id = TEGRA30_CLK_MSELECT },
 	{ .dev_id = "tegra-nor", .dt_id = TEGRA30_CLK_NOR },
@@ -762,6 +766,10 @@  static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = {
 	[tegra_clk_host1x] = { .dt_id = TEGRA30_CLK_HOST1X, .present = true },
 	[tegra_clk_gr2d] = { .dt_id = TEGRA30_CLK_GR2D, .present = true },
 	[tegra_clk_gr3d] = { .dt_id = TEGRA30_CLK_GR3D, .present = true },
+	[tegra_clk_gr2d_mux] = { .dt_id = TEGRA30_CLK_GR2D_MUX, .present = true },
+	[tegra_clk_gr3d_mux] = { .dt_id = TEGRA30_CLK_GR3D_MUX, .present = true },
+	[tegra_clk_gr2d_idle] = { .dt_id = TEGRA30_CLK_GR2D_IDLE, .present = true },
+	[tegra_clk_gr3d_idle] = { .dt_id = TEGRA30_CLK_GR3D_IDLE, .present = true },
 	[tegra_clk_mselect] = { .dt_id = TEGRA30_CLK_MSELECT, .present = true },
 	[tegra_clk_nor] = { .dt_id = TEGRA30_CLK_NOR, .present = true },
 	[tegra_clk_sdmmc1] = { .dt_id = TEGRA30_CLK_SDMMC1, .present = true },
diff --git a/include/dt-bindings/clock/tegra30-car.h b/include/dt-bindings/clock/tegra30-car.h
index 3c90f1535551..eda4ca60351e 100644
--- a/include/dt-bindings/clock/tegra30-car.h
+++ b/include/dt-bindings/clock/tegra30-car.h
@@ -269,6 +269,11 @@ 
 #define TEGRA30_CLK_AUDIO3_MUX 306
 #define TEGRA30_CLK_AUDIO4_MUX 307
 #define TEGRA30_CLK_SPDIF_MUX 308
-#define TEGRA30_CLK_CLK_MAX 309
+
+#define TEGRA30_CLK_GR2D_MUX	309
+#define TEGRA30_CLK_GR3D_MUX	310
+#define TEGRA30_CLK_GR2D_IDLE	311
+#define TEGRA30_CLK_GR3D_IDLE	312
+#define TEGRA30_CLK_CLK_MAX 313
 
 #endif	/* _DT_BINDINGS_CLOCK_TEGRA30_CAR_H */