Tegra,Tegra124: proposed layout for file hierarchy with example
This change shows the source structure for nvidia Tegra and Tegra124
SOC. The problem we are trying to solve is that there is a large
amount of common code in the form of .c and .h files across many
different Tegra SOCs. The solution is to provide common code in a
single directory, but not to compile in the common code directory;
rather, we compile in a directory for a given SOC. Different SOCs
will sometimes need different bits of code from the common directory.
Tegra common code lives in tegra/, but there is no makefile there: if
a Tegra common file is needed in a SOC, it is referenced via a
Makefile in a specific Tegra SOC.
Another issue is includes. Include files in the common directory might be
accessed by a piece of code in an SOC directory. More problematically,
code in the common directory might require a file in an SOC directory.
We don't want to put the SOC name in an #include path, e.g.
in a C file in tegra/ is very undesirable, since we might be compiling
for a tegra114.
On some systems this is solved by a pre-pass which creates a set of
symbolic links; on others with nested #ifdef in the common code
which include different .h files depending on CPP variables.
In previous years, both LinuxBIOS and coreboot have tried these
solutions and found them inconvenient and error-prone.
We choose to solve it by requiring explicit naming of part of the path
of files that are in the common directory. This requirement, coupled
with two -I directives in the Makefile.inc, allows common and SOC
C code to incorporate both common and SOC .h files.
.c and .h files -- SOC or common -- name include
files in the common directory with the prefix tegra/, e.g.
SOC files will be included from the SOC directory if they have no prefix:
The full patch of clock.h will depend on what SOC is being compiled, which
is desirable.
In this way, a common file can pick up a specific SOC file without
creating symlinks or other such tricky magic.
We show this usage with one file, soc/nvidia/tega124/clock.c. This compiles.
The last question is where to put the prototype for the function
defined in this file -- soc.h?
Change-Id: Iecb635cec70f24a5b3e18caeda09d04a00d29409
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: https://chromium-review.googlesource.com/171569
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 53e3bed868953f3da588ec90661d316a6482e27e)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6621
Tested-by: build bot (Jenkins)
2013-10-04 02:05:55 +02:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
|
2014-03-04 01:26:11 +01:00
|
|
|
* Copyright 2014 Google Inc.
|
Tegra,Tegra124: proposed layout for file hierarchy with example
This change shows the source structure for nvidia Tegra and Tegra124
SOC. The problem we are trying to solve is that there is a large
amount of common code in the form of .c and .h files across many
different Tegra SOCs. The solution is to provide common code in a
single directory, but not to compile in the common code directory;
rather, we compile in a directory for a given SOC. Different SOCs
will sometimes need different bits of code from the common directory.
Tegra common code lives in tegra/, but there is no makefile there: if
a Tegra common file is needed in a SOC, it is referenced via a
Makefile in a specific Tegra SOC.
Another issue is includes. Include files in the common directory might be
accessed by a piece of code in an SOC directory. More problematically,
code in the common directory might require a file in an SOC directory.
We don't want to put the SOC name in an #include path, e.g.
in a C file in tegra/ is very undesirable, since we might be compiling
for a tegra114.
On some systems this is solved by a pre-pass which creates a set of
symbolic links; on others with nested #ifdef in the common code
which include different .h files depending on CPP variables.
In previous years, both LinuxBIOS and coreboot have tried these
solutions and found them inconvenient and error-prone.
We choose to solve it by requiring explicit naming of part of the path
of files that are in the common directory. This requirement, coupled
with two -I directives in the Makefile.inc, allows common and SOC
C code to incorporate both common and SOC .h files.
.c and .h files -- SOC or common -- name include
files in the common directory with the prefix tegra/, e.g.
SOC files will be included from the SOC directory if they have no prefix:
The full patch of clock.h will depend on what SOC is being compiled, which
is desirable.
In this way, a common file can pick up a specific SOC file without
creating symlinks or other such tricky magic.
We show this usage with one file, soc/nvidia/tega124/clock.c. This compiles.
The last question is where to put the prototype for the function
defined in this file -- soc.h?
Change-Id: Iecb635cec70f24a5b3e18caeda09d04a00d29409
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: https://chromium-review.googlesource.com/171569
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 53e3bed868953f3da588ec90661d316a6482e27e)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6621
Tested-by: build bot (Jenkins)
2013-10-04 02:05:55 +02:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU General Public License,
|
|
|
|
* version 2, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2013-10-10 08:45:07 +02:00
|
|
|
#include <console/console.h>
|
Tegra,Tegra124: proposed layout for file hierarchy with example
This change shows the source structure for nvidia Tegra and Tegra124
SOC. The problem we are trying to solve is that there is a large
amount of common code in the form of .c and .h files across many
different Tegra SOCs. The solution is to provide common code in a
single directory, but not to compile in the common code directory;
rather, we compile in a directory for a given SOC. Different SOCs
will sometimes need different bits of code from the common directory.
Tegra common code lives in tegra/, but there is no makefile there: if
a Tegra common file is needed in a SOC, it is referenced via a
Makefile in a specific Tegra SOC.
Another issue is includes. Include files in the common directory might be
accessed by a piece of code in an SOC directory. More problematically,
code in the common directory might require a file in an SOC directory.
We don't want to put the SOC name in an #include path, e.g.
in a C file in tegra/ is very undesirable, since we might be compiling
for a tegra114.
On some systems this is solved by a pre-pass which creates a set of
symbolic links; on others with nested #ifdef in the common code
which include different .h files depending on CPP variables.
In previous years, both LinuxBIOS and coreboot have tried these
solutions and found them inconvenient and error-prone.
We choose to solve it by requiring explicit naming of part of the path
of files that are in the common directory. This requirement, coupled
with two -I directives in the Makefile.inc, allows common and SOC
C code to incorporate both common and SOC .h files.
.c and .h files -- SOC or common -- name include
files in the common directory with the prefix tegra/, e.g.
SOC files will be included from the SOC directory if they have no prefix:
The full patch of clock.h will depend on what SOC is being compiled, which
is desirable.
In this way, a common file can pick up a specific SOC file without
creating symlinks or other such tricky magic.
We show this usage with one file, soc/nvidia/tega124/clock.c. This compiles.
The last question is where to put the prototype for the function
defined in this file -- soc.h?
Change-Id: Iecb635cec70f24a5b3e18caeda09d04a00d29409
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: https://chromium-review.googlesource.com/171569
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 53e3bed868953f3da588ec90661d316a6482e27e)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6621
Tested-by: build bot (Jenkins)
2013-10-04 02:05:55 +02:00
|
|
|
#include <delay.h>
|
|
|
|
#include <arch/io.h>
|
tegra: Change how tegra124 and tegra include files from each other.
A problem with including the tegra124 directory directly in the include path
is that it makes all headers in that directory first level headers available
everywhere including places that have nothing to do with the SOC, even headers
which were only intended for local use by tegra124 code. This change modifies
things a bit to be more like the way the arch headers are chosen. In the
tegra124 directory, there's an include directory which has an soc subdirectory
in it. That include directory is added to the include path, making it possible
to have headers private to the tegra124. When files specific to whatever tegra
is being built for are needed, you can include <soc/foo.h> and get the version
specific to that particular soc.
Also, the soc.h header file was overhauled to use enums instead of defines, to
consistently name things as far as their prefix (the less cryptic TEGRA instead
of NV_PA) and suffixes like "BASE", and to get rid of values which were
specific to U-Boot which we don't need. Since the only thing in the file were
address constants, I also renamed the file addressmap.h. It would be included
as:
<soc/addressmap.h>
which I think is easy to remember, does what you'd think it does from the
name, and won't conflict with other header files just minding their own
business in some other directory.
Change-Id: I6a1be1ba28417b7103ad8584e6ec5024a7ff4e55
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: https://chromium-review.googlesource.com/172080
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 2c554f58f9ee18e151e824f01c03eb3f0e907858)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6659
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2013-10-06 15:13:24 +02:00
|
|
|
#include <soc/addressmap.h>
|
2013-10-10 08:45:07 +02:00
|
|
|
#include <soc/clock.h>
|
2013-10-21 15:43:03 +02:00
|
|
|
#include <stdlib.h>
|
tegra: Change how tegra124 and tegra include files from each other.
A problem with including the tegra124 directory directly in the include path
is that it makes all headers in that directory first level headers available
everywhere including places that have nothing to do with the SOC, even headers
which were only intended for local use by tegra124 code. This change modifies
things a bit to be more like the way the arch headers are chosen. In the
tegra124 directory, there's an include directory which has an soc subdirectory
in it. That include directory is added to the include path, making it possible
to have headers private to the tegra124. When files specific to whatever tegra
is being built for are needed, you can include <soc/foo.h> and get the version
specific to that particular soc.
Also, the soc.h header file was overhauled to use enums instead of defines, to
consistently name things as far as their prefix (the less cryptic TEGRA instead
of NV_PA) and suffixes like "BASE", and to get rid of values which were
specific to U-Boot which we don't need. Since the only thing in the file were
address constants, I also renamed the file addressmap.h. It would be included
as:
<soc/addressmap.h>
which I think is easy to remember, does what you'd think it does from the
name, and won't conflict with other header files just minding their own
business in some other directory.
Change-Id: I6a1be1ba28417b7103ad8584e6ec5024a7ff4e55
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: https://chromium-review.googlesource.com/172080
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 2c554f58f9ee18e151e824f01c03eb3f0e907858)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6659
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2013-10-06 15:13:24 +02:00
|
|
|
#include "clk_rst.h"
|
2013-10-10 08:45:07 +02:00
|
|
|
#include "flow.h"
|
2013-10-26 02:49:26 +02:00
|
|
|
#include "maincpu.h"
|
2013-10-10 08:45:07 +02:00
|
|
|
#include "pmc.h"
|
2013-10-21 15:43:03 +02:00
|
|
|
#include "sysctr.h"
|
tegra: Change how tegra124 and tegra include files from each other.
A problem with including the tegra124 directory directly in the include path
is that it makes all headers in that directory first level headers available
everywhere including places that have nothing to do with the SOC, even headers
which were only intended for local use by tegra124 code. This change modifies
things a bit to be more like the way the arch headers are chosen. In the
tegra124 directory, there's an include directory which has an soc subdirectory
in it. That include directory is added to the include path, making it possible
to have headers private to the tegra124. When files specific to whatever tegra
is being built for are needed, you can include <soc/foo.h> and get the version
specific to that particular soc.
Also, the soc.h header file was overhauled to use enums instead of defines, to
consistently name things as far as their prefix (the less cryptic TEGRA instead
of NV_PA) and suffixes like "BASE", and to get rid of values which were
specific to U-Boot which we don't need. Since the only thing in the file were
address constants, I also renamed the file addressmap.h. It would be included
as:
<soc/addressmap.h>
which I think is easy to remember, does what you'd think it does from the
name, and won't conflict with other header files just minding their own
business in some other directory.
Change-Id: I6a1be1ba28417b7103ad8584e6ec5024a7ff4e55
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: https://chromium-review.googlesource.com/172080
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 2c554f58f9ee18e151e824f01c03eb3f0e907858)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6659
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2013-10-06 15:13:24 +02:00
|
|
|
|
|
|
|
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
2013-10-10 08:45:07 +02:00
|
|
|
static struct flow_ctlr *flow = (void *)TEGRA_FLOW_BASE;
|
2013-10-21 15:43:03 +02:00
|
|
|
static struct tegra_pmc_regs *pmc = (void *)TEGRA_PMC_BASE;
|
|
|
|
static struct sysctr_regs *sysctr = (void *)TEGRA_SYSCTR0_BASE;
|
2013-10-10 08:45:07 +02:00
|
|
|
|
|
|
|
struct pll_dividers {
|
|
|
|
u32 n : 10;
|
|
|
|
u32 m : 8;
|
|
|
|
u32 p : 4;
|
2014-03-04 20:06:13 +01:00
|
|
|
u32 cpcon : 4;
|
|
|
|
u32 lfcon : 4;
|
|
|
|
u32 : 2;
|
2013-10-10 08:45:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Some PLLs have more restrictive divider bit lengths or are missing some
|
|
|
|
* fields. Make sure to use the right struct in the osc_table definition to get
|
|
|
|
* compile-time checking, but keep the bits aligned with struct pll_dividers so
|
|
|
|
* they can be used interchangeably at run time. Add new formats as required. */
|
|
|
|
struct pllcx_dividers {
|
|
|
|
u32 n : 8;
|
|
|
|
u32 : 2;
|
|
|
|
u32 m : 8;
|
|
|
|
u32 p : 4;
|
|
|
|
u32 : 10;
|
|
|
|
};
|
|
|
|
struct pllpad_dividers {
|
|
|
|
u32 n : 10;
|
|
|
|
u32 m : 5;
|
|
|
|
u32 : 3;
|
|
|
|
u32 p : 3;
|
|
|
|
u32 : 1;
|
|
|
|
u32 cpcon : 4;
|
|
|
|
u32 : 6;
|
|
|
|
};
|
|
|
|
struct pllu_dividers {
|
|
|
|
u32 n : 10;
|
|
|
|
u32 m : 5;
|
|
|
|
u32 : 3;
|
|
|
|
u32 p : 1;
|
|
|
|
u32 : 3;
|
|
|
|
u32 cpcon : 4;
|
2014-03-04 20:06:13 +01:00
|
|
|
u32 lfcon : 4;
|
|
|
|
u32 : 2;
|
2013-10-10 08:45:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
union __attribute__((transparent_union)) pll_fields {
|
|
|
|
u32 raw;
|
|
|
|
struct pll_dividers div;
|
|
|
|
struct pllcx_dividers cx;
|
|
|
|
struct pllpad_dividers pad;
|
|
|
|
struct pllu_dividers u;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* This table defines the frequency dividers for every PLL to turn the external
|
|
|
|
* OSC clock into the frequencies defined by TEGRA_PLL*_KHZ in soc/clock.h.
|
|
|
|
* All PLLs have three dividers (N, M and P), with the governing formula for
|
2013-10-26 02:49:26 +02:00
|
|
|
* the output frequency being OUT = (IN / m) * N / (2^P).
|
|
|
|
* Yes, it really is one equation with three unknowns ... */
|
2013-10-10 08:45:07 +02:00
|
|
|
struct {
|
|
|
|
int khz;
|
2014-03-04 01:26:11 +01:00
|
|
|
struct pllcx_dividers pllx; /* target: CONFIG_PLLX_KHZ */
|
2013-10-10 08:45:07 +02:00
|
|
|
struct pllcx_dividers pllc; /* target: 600 MHz */
|
|
|
|
struct pllu_dividers pllu; /* target; 960 MHz */
|
2013-10-26 02:49:26 +02:00
|
|
|
struct pllcx_dividers plldp; /* target; 270 MHz */
|
2014-03-05 20:12:25 +01:00
|
|
|
/* Based on T124 TRM (to be updatd), PLLP is set to 408MHz in HW.
|
|
|
|
* Unless configuring PLLP to a frequency other than 408MHz,
|
|
|
|
* software configuration on PLLP is unneeded. */
|
2013-10-10 08:45:07 +02:00
|
|
|
} static const osc_table[16] = {
|
|
|
|
[OSC_FREQ_OSC12]{
|
|
|
|
.khz = 12000,
|
2014-03-04 01:26:11 +01:00
|
|
|
.pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
|
2013-10-10 08:45:07 +02:00
|
|
|
.pllc = {.n = 50, .m = 1, .p = 0},
|
2014-03-04 20:06:13 +01:00
|
|
|
.pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
.plldp = {.n = 90, .m = 1, .p = 3},
|
2013-10-10 08:45:07 +02:00
|
|
|
},
|
|
|
|
[OSC_FREQ_OSC13]{
|
|
|
|
.khz = 13000,
|
2014-03-04 01:26:11 +01:00
|
|
|
.pllx = {.n = TEGRA_PLLX_KHZ / 13000, .m = 1, .p = 0},
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
.pllc = {.n = 231, .m = 5, .p = 0}, /* 600.6 MHz */
|
2014-03-04 20:06:13 +01:00
|
|
|
.pllu = {.n = 960, .m = 13, .p = 0, .cpcon = 12, .lfcon = 2},
|
2013-10-26 02:49:26 +02:00
|
|
|
.plldp = {.n = 83, .m = 1, .p = 3}, /* 269.75 MHz */
|
2013-10-10 08:45:07 +02:00
|
|
|
},
|
|
|
|
[OSC_FREQ_OSC16P8]{
|
|
|
|
.khz = 16800,
|
2014-03-04 01:26:11 +01:00
|
|
|
.pllx = {.n = TEGRA_PLLX_KHZ / 16800, .m = 1, .p = 0},
|
2013-10-10 08:45:07 +02:00
|
|
|
.pllc = {.n = 250, .m = 7, .p = 0},
|
2014-03-04 20:06:13 +01:00
|
|
|
.pllu = {.n = 400, .m = 7, .p = 0, .cpcon = 5, .lfcon = 2},
|
2013-10-26 02:49:26 +02:00
|
|
|
.plldp = {.n = 64, .m = 1, .p = 3}, /* 268.8 MHz */
|
2013-10-10 08:45:07 +02:00
|
|
|
},
|
|
|
|
[OSC_FREQ_OSC19P2]{
|
|
|
|
.khz = 19200,
|
2014-03-04 01:26:11 +01:00
|
|
|
.pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
|
2013-10-10 08:45:07 +02:00
|
|
|
.pllc = {.n = 125, .m = 4, .p = 0},
|
2014-03-04 20:06:13 +01:00
|
|
|
.pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
|
2013-10-26 02:49:26 +02:00
|
|
|
.plldp = {.n = 56, .m = 1, .p = 3}, /* 270.75 MHz */
|
2013-10-10 08:45:07 +02:00
|
|
|
},
|
|
|
|
[OSC_FREQ_OSC26]{
|
|
|
|
.khz = 26000,
|
2014-03-04 01:26:11 +01:00
|
|
|
.pllx = {.n = TEGRA_PLLX_KHZ / 26000, .m = 1, .p = 0},
|
2013-10-10 08:45:07 +02:00
|
|
|
.pllc = {.n = 23, .m = 1, .p = 0}, /* 598 MHz */
|
2014-03-04 20:06:13 +01:00
|
|
|
.pllu = {.n = 960, .m = 26, .p = 0, .cpcon = 12, .lfcon = 2},
|
2013-10-26 02:49:26 +02:00
|
|
|
.plldp = {.n = 83, .m = 2, .p = 3}, /* 266.50 MHz */
|
2013-10-10 08:45:07 +02:00
|
|
|
},
|
|
|
|
[OSC_FREQ_OSC38P4]{
|
|
|
|
.khz = 38400,
|
2014-03-04 01:26:11 +01:00
|
|
|
/*
|
|
|
|
* There is a predivide by 2 before this PLL. Its values
|
|
|
|
* should match the 19.2MHz values.
|
|
|
|
*/
|
|
|
|
.pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
|
2013-10-10 08:45:07 +02:00
|
|
|
.pllc = {.n = 125, .m = 4, .p = 0},
|
2014-03-04 20:06:13 +01:00
|
|
|
.pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
|
2013-10-26 02:49:26 +02:00
|
|
|
.plldp = {.n = 56, .m = 2, .p = 3}, /* 268 MHz */
|
2013-10-10 08:45:07 +02:00
|
|
|
},
|
|
|
|
[OSC_FREQ_OSC48]{
|
|
|
|
.khz = 48000,
|
2014-03-04 01:26:11 +01:00
|
|
|
/*
|
|
|
|
* There is a predivide by 4 before this PLL. Its values
|
|
|
|
* should match the 12MHz values.
|
|
|
|
*/
|
|
|
|
.pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
|
2013-10-10 08:45:07 +02:00
|
|
|
.pllc = {.n = 50, .m = 1, .p = 0},
|
2014-03-04 20:06:13 +01:00
|
|
|
.pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
|
2013-10-26 02:49:26 +02:00
|
|
|
.plldp = {.n = 90, .m = 4, .p = 3}, /* 264 MHz */
|
2013-10-10 08:45:07 +02:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Get the oscillator frequency, from the corresponding hardware
|
|
|
|
* configuration field. This is actually a per-soc thing. Avoid the
|
|
|
|
* temptation to make it common.
|
Tegra,Tegra124: proposed layout for file hierarchy with example
This change shows the source structure for nvidia Tegra and Tegra124
SOC. The problem we are trying to solve is that there is a large
amount of common code in the form of .c and .h files across many
different Tegra SOCs. The solution is to provide common code in a
single directory, but not to compile in the common code directory;
rather, we compile in a directory for a given SOC. Different SOCs
will sometimes need different bits of code from the common directory.
Tegra common code lives in tegra/, but there is no makefile there: if
a Tegra common file is needed in a SOC, it is referenced via a
Makefile in a specific Tegra SOC.
Another issue is includes. Include files in the common directory might be
accessed by a piece of code in an SOC directory. More problematically,
code in the common directory might require a file in an SOC directory.
We don't want to put the SOC name in an #include path, e.g.
in a C file in tegra/ is very undesirable, since we might be compiling
for a tegra114.
On some systems this is solved by a pre-pass which creates a set of
symbolic links; on others with nested #ifdef in the common code
which include different .h files depending on CPP variables.
In previous years, both LinuxBIOS and coreboot have tried these
solutions and found them inconvenient and error-prone.
We choose to solve it by requiring explicit naming of part of the path
of files that are in the common directory. This requirement, coupled
with two -I directives in the Makefile.inc, allows common and SOC
C code to incorporate both common and SOC .h files.
.c and .h files -- SOC or common -- name include
files in the common directory with the prefix tegra/, e.g.
SOC files will be included from the SOC directory if they have no prefix:
The full patch of clock.h will depend on what SOC is being compiled, which
is desirable.
In this way, a common file can pick up a specific SOC file without
creating symlinks or other such tricky magic.
We show this usage with one file, soc/nvidia/tega124/clock.c. This compiles.
The last question is where to put the prototype for the function
defined in this file -- soc.h?
Change-Id: Iecb635cec70f24a5b3e18caeda09d04a00d29409
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: https://chromium-review.googlesource.com/171569
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 53e3bed868953f3da588ec90661d316a6482e27e)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6621
Tested-by: build bot (Jenkins)
2013-10-04 02:05:55 +02:00
|
|
|
*/
|
2013-10-10 08:45:07 +02:00
|
|
|
static u32 clock_get_osc_bits(void)
|
|
|
|
{
|
|
|
|
return readl(&clk_rst->osc_ctrl) >> OSC_CTRL_OSC_FREQ_SHIFT;
|
|
|
|
}
|
|
|
|
|
|
|
|
int clock_get_osc_khz(void)
|
|
|
|
{
|
|
|
|
return osc_table[clock_get_osc_bits()].khz;
|
|
|
|
}
|
|
|
|
|
2013-10-21 15:43:03 +02:00
|
|
|
void clock_init_arm_generic_timer(void)
|
|
|
|
{
|
|
|
|
uint32_t freq = clock_get_osc_khz() * 1000;
|
|
|
|
// Set the cntfrq register.
|
|
|
|
__asm__ __volatile__("mcr p15, 0, %0, c14, c0, 0\n" :: "r"(freq));
|
|
|
|
|
|
|
|
// Record the system timer frequency.
|
|
|
|
write32(freq, &sysctr->cntfid0);
|
|
|
|
// Enable the system counter.
|
|
|
|
uint32_t cntcr = read32(&sysctr->cntcr);
|
|
|
|
cntcr |= SYSCTR_CNTCR_EN | SYSCTR_CNTCR_HDBG;
|
|
|
|
write32(cntcr, &sysctr->cntcr);
|
|
|
|
}
|
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
#define SOR0_CLK_SEL0 (1 << 14)
|
|
|
|
#define SOR0_CLK_SEL1 (1 << 15)
|
|
|
|
|
|
|
|
void sor_clock_stop(void)
|
|
|
|
{
|
|
|
|
/* The Serial Output Resource clock has to be off
|
|
|
|
* before we start the plldp. Learned the hard way.
|
|
|
|
* FIXME: this has to be cleaned up a bit more.
|
|
|
|
* Waiting on some new info from Nvidia.
|
|
|
|
*/
|
|
|
|
clrbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0 | SOR0_CLK_SEL1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sor_clock_start(void)
|
2013-10-10 08:45:07 +02:00
|
|
|
{
|
2013-10-26 02:49:26 +02:00
|
|
|
/* uses PLLP, has a non-standard bit layout. */
|
|
|
|
setbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0);
|
2013-10-10 08:45:07 +02:00
|
|
|
}
|
|
|
|
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
static void init_pll(u32 *base, u32 *misc, const union pll_fields pll, u32 lock)
|
2013-10-10 08:45:07 +02:00
|
|
|
{
|
|
|
|
u32 dividers = pll.div.n << PLL_BASE_DIVN_SHIFT |
|
|
|
|
pll.div.m << PLL_BASE_DIVM_SHIFT |
|
|
|
|
pll.div.p << PLL_BASE_DIVP_SHIFT;
|
2014-03-04 20:06:13 +01:00
|
|
|
u32 misc_con = pll.div.cpcon << PLL_MISC_CPCON_SHIFT |
|
|
|
|
pll.div.lfcon << PLL_MISC_LFCON_SHIFT;
|
2013-10-10 08:45:07 +02:00
|
|
|
|
|
|
|
/* Write dividers but BYPASS the PLL while we're messing with it. */
|
|
|
|
writel(dividers | PLL_BASE_BYPASS, base);
|
2014-03-04 20:06:13 +01:00
|
|
|
/*
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
* Set Lock bit, CPCON and LFCON fields (default to 0 if it doesn't
|
|
|
|
* exist for this PLL)
|
2014-03-04 20:06:13 +01:00
|
|
|
*/
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
writel(lock | misc_con, misc);
|
2013-10-10 08:45:07 +02:00
|
|
|
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
/* Enable PLL and take it back out of BYPASS */
|
2013-10-10 08:45:07 +02:00
|
|
|
writel(dividers | PLL_BASE_ENABLE, base);
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
|
|
|
|
/* Wait for lock ready */
|
|
|
|
while (!(readl(base) & PLL_BASE_LOCK));
|
2013-10-10 08:45:07 +02:00
|
|
|
}
|
|
|
|
|
2013-10-21 15:43:03 +02:00
|
|
|
static void init_utmip_pll(void)
|
|
|
|
{
|
|
|
|
int khz = clock_get_osc_khz();
|
|
|
|
|
|
|
|
/* Shut off PLL crystal clock while we mess with it */
|
|
|
|
clrbits_le32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
|
|
|
|
udelay(1);
|
|
|
|
|
|
|
|
write32(80 << 16 | /* (rst) phy_divn */
|
|
|
|
1 << 8 | /* (rst) phy_divm */
|
|
|
|
0, &clk_rst->utmip_pll_cfg0); /* 960MHz * 1 / 80 == 12 MHz */
|
|
|
|
|
|
|
|
write32(CEIL_DIV(khz, 8000) << 27 | /* pllu_enbl_cnt / 8 (1us) */
|
|
|
|
0 << 16 | /* PLLU pwrdn */
|
|
|
|
0 << 14 | /* pll_enable pwrdn */
|
|
|
|
0 << 12 | /* pll_active pwrdn */
|
|
|
|
CEIL_DIV(khz, 102) << 0 | /* phy_stbl_cnt / 256 (2.5ms) */
|
|
|
|
0, &clk_rst->utmip_pll_cfg1);
|
|
|
|
|
|
|
|
/* TODO: TRM can't decide if actv is 5us or 10us, keep an eye on it */
|
|
|
|
write32(0 << 24 | /* SAMP_D/XDEV pwrdn */
|
|
|
|
CEIL_DIV(khz, 3200) << 18 | /* phy_actv_cnt / 16 (5us) */
|
|
|
|
CEIL_DIV(khz, 256) << 6 | /* pllu_stbl_cnt / 256 (1ms) */
|
|
|
|
0 << 4 | /* SAMP_C/USB3 pwrdn */
|
|
|
|
0 << 2 | /* SAMP_B/XHOST pwrdn */
|
|
|
|
0 << 0 | /* SAMP_A/USBD pwrdn */
|
|
|
|
0, &clk_rst->utmip_pll_cfg2);
|
|
|
|
|
|
|
|
setbits_le32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
|
|
|
|
}
|
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
/* Graphics just has to be different. There's a few more bits we
|
|
|
|
* need to set in here, but it makes sense just to restrict all the
|
|
|
|
* special bits to this one function.
|
|
|
|
*/
|
|
|
|
static void graphics_pll(void)
|
|
|
|
{
|
|
|
|
int osc = clock_get_osc_bits();
|
|
|
|
u32 *cfg = &clk_rst->plldp_ss_cfg;
|
|
|
|
/* the vendor code sets the dither bit (28)
|
|
|
|
* an undocumented bit (24)
|
|
|
|
* and clamp while we mess with it (22)
|
|
|
|
* Dither is pretty important to display port
|
|
|
|
* so we really do need to handle these bits.
|
|
|
|
* I'm not willing to not clamp it, even if
|
|
|
|
* it might "mostly work" with it not set,
|
|
|
|
* I don't want to find out in a few months
|
|
|
|
* that it is needed.
|
|
|
|
*/
|
|
|
|
u32 scfg = (1<<28) | (1<<24) | (1<<22);
|
|
|
|
writel(scfg, cfg);
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
init_pll(&clk_rst->plldp_base, &clk_rst->plldp_misc,
|
|
|
|
osc_table[osc].plldp, PLLDPD2_MISC_LOCK_ENABLE);
|
2013-10-26 02:49:26 +02:00
|
|
|
/* leave dither and undoc bits set, release clamp */
|
|
|
|
scfg = (1<<28) | (1<<24);
|
|
|
|
writel(scfg, cfg);
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
|
2014-04-08 14:03:40 +02:00
|
|
|
/* disp1 will be set when panel information (pixel clock) is
|
|
|
|
* retrieved (clock_display).
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Init PLLD clock source. */
|
|
|
|
int
|
|
|
|
clock_display(u32 frequency)
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* plld (fo) = vco >> p, where 500MHz < vco < 1000MHz
|
|
|
|
* = (cf * n) >> p, where 1MHz < cf < 6MHz
|
|
|
|
* = ((ref / m) * n) >> p
|
|
|
|
*
|
|
|
|
* Assume p = 0, find (m, n). since m has only 5 bits, we can iterate
|
|
|
|
* all possible values. Note Tegra 124 supports 11 bits for n, but our
|
|
|
|
* pll_fields has only 10 bits for n.
|
|
|
|
*
|
|
|
|
* Note values undershoot or overshoot target output frequency may not
|
|
|
|
* work if the value is not in "safe" range in panel specification, so
|
|
|
|
* we want exact match.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct pllpad_dividers plld = { 0 };
|
|
|
|
u32 ref = clock_get_osc_khz() * 1000, m, n;
|
|
|
|
u32 cf, vco = frequency;
|
|
|
|
const u32 max_m = 1 << 5, max_n = 1 << 10, mhz = 1000 * 1000,
|
|
|
|
min_vco = 500 * mhz, max_vco = 1000 * mhz,
|
|
|
|
min_cf = 1 * mhz, max_cf = 6 * mhz;
|
|
|
|
|
|
|
|
/* TODO(hungte) Replace this by clock_get_pll_input_khz */
|
|
|
|
switch (clock_get_osc_bits()) {
|
|
|
|
case OSC_FREQ_OSC48:
|
|
|
|
ref /= 4;
|
|
|
|
break;
|
|
|
|
case OSC_FREQ_OSC38P4:
|
|
|
|
ref /= 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vco < min_vco || vco > max_vco) {
|
|
|
|
printk(BIOS_ERR, "%s: VCO (%d) out of range. Cannot support.\n",
|
|
|
|
__func__, vco);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (m = 1; m < max_m; m++) {
|
|
|
|
cf = ref / m;
|
|
|
|
if (cf < min_cf)
|
|
|
|
break;
|
|
|
|
|
|
|
|
n = vco / cf;
|
|
|
|
if (vco != cf * n || n >= max_n || cf > max_cf)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
plld.m = m;
|
|
|
|
plld.n = n;
|
|
|
|
|
|
|
|
if (n < 50)
|
|
|
|
plld.cpcon = 2;
|
|
|
|
else if (n < 300)
|
|
|
|
plld.cpcon = 3;
|
|
|
|
else if (n < 600)
|
|
|
|
plld.cpcon = 8;
|
|
|
|
else
|
|
|
|
plld.cpcon = 12;
|
|
|
|
|
|
|
|
printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p/cpcon="
|
|
|
|
"%u/%u/%u/%u\n", __func__,
|
|
|
|
(ref / plld.m * plld.n) >> plld.p, ref,
|
|
|
|
plld.m, plld.n, plld.p, plld.cpcon);
|
|
|
|
|
|
|
|
init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, plld,
|
|
|
|
(PLLUD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
printk(BIOS_ERR, "%s: Failed to match output frequency %u.\n",
|
|
|
|
__func__, frequency);
|
|
|
|
return -1;
|
2013-10-26 02:49:26 +02:00
|
|
|
}
|
|
|
|
|
2013-10-10 08:45:07 +02:00
|
|
|
/* Initialize the UART and put it on CLK_M so we can use it during clock_init().
|
|
|
|
* Will later move it to PLLP in clock_config(). The divisor must be very small
|
|
|
|
* to accomodate 12KHz OSCs, so we override the 16.0 UART divider with the 15.1
|
|
|
|
* CLK_SOURCE divider to get more precision. (This might still not be enough for
|
tegra124: A couple clock fixes.
This fixes two problems with the clock configuration on tegra124. First, the
macro which set up the i2c clocks tried to account for the fact that the i2c
divisor's lsb represents 1.0 where it normally represents 0.5 by multiplying
the target frequency by 2. That doesn't work, unfortunately, because the
divisor is actually n + 1, and what n + 1 means depends on where the one's
place is in the divisor.
Also, when calculating the divisor, the standard C division operator uses
truncation to deal any remainder which tends to make the divisor smaller. That
has the effect of making the output frequency higher than what was requested.
Since it's usually safer to undershoot a frequency than overshoot it, this
change makes those divisions round up instead.
Finally, the hand tuned temporary UART clock configuration was adjusted so
that it still ends up with the same divisor. Without that, very early output
from the bootblock is garbled, specifically the coreboot welcome banner,
build timestamp, etc.
BUG=chrome-os-partner:27220
TEST=Built and booted on nyan. Used a logic analyzer to verify that the TPM
i2c bus ran at 400KHz instead of 660KHz, and that the divisor was the expected
value. Measured boot time with and without EFS and verified that there was no
change. Spot checked the output for errors and verified that none of the
bootblock output was garbled.
BRANCH=None
Had to add the stdlib.h from 89ed6c that hadn't been merged correctly.
Original-Change-Id: I7e948c361ed4bf58c608627d32f2e3424faea1fb
Original-Signed-off-by: Gabe Black <gabeblack@google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/193362
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Original-Commit-Queue: Gabe Black <gabeblack@chromium.org>
Original-Tested-by: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 164f7010a47d3bbdbc8bb572106140ae186f3807)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I317b66eda929c0e5a5832adca267b8b54c6aae34
Reviewed-on: http://review.coreboot.org/7736
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-04-05 12:54:30 +02:00
|
|
|
* some OSCs... if you use 13KHz, be prepared to have a bad time.) The 1900 has
|
2013-10-10 08:45:07 +02:00
|
|
|
* been determined through trial and error (must lead to div 13 at 24MHz). */
|
|
|
|
void clock_early_uart(void)
|
|
|
|
{
|
2013-10-21 15:43:03 +02:00
|
|
|
write32(CLK_M << CLK_SOURCE_SHIFT | CLK_UART_DIV_OVERRIDE |
|
tegra124: A couple clock fixes.
This fixes two problems with the clock configuration on tegra124. First, the
macro which set up the i2c clocks tried to account for the fact that the i2c
divisor's lsb represents 1.0 where it normally represents 0.5 by multiplying
the target frequency by 2. That doesn't work, unfortunately, because the
divisor is actually n + 1, and what n + 1 means depends on where the one's
place is in the divisor.
Also, when calculating the divisor, the standard C division operator uses
truncation to deal any remainder which tends to make the divisor smaller. That
has the effect of making the output frequency higher than what was requested.
Since it's usually safer to undershoot a frequency than overshoot it, this
change makes those divisions round up instead.
Finally, the hand tuned temporary UART clock configuration was adjusted so
that it still ends up with the same divisor. Without that, very early output
from the bootblock is garbled, specifically the coreboot welcome banner,
build timestamp, etc.
BUG=chrome-os-partner:27220
TEST=Built and booted on nyan. Used a logic analyzer to verify that the TPM
i2c bus ran at 400KHz instead of 660KHz, and that the divisor was the expected
value. Measured boot time with and without EFS and verified that there was no
change. Spot checked the output for errors and verified that none of the
bootblock output was garbled.
BRANCH=None
Had to add the stdlib.h from 89ed6c that hadn't been merged correctly.
Original-Change-Id: I7e948c361ed4bf58c608627d32f2e3424faea1fb
Original-Signed-off-by: Gabe Black <gabeblack@google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/193362
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Original-Commit-Queue: Gabe Black <gabeblack@chromium.org>
Original-Tested-by: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 164f7010a47d3bbdbc8bb572106140ae186f3807)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I317b66eda929c0e5a5832adca267b8b54c6aae34
Reviewed-on: http://review.coreboot.org/7736
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-04-05 12:54:30 +02:00
|
|
|
CLK_DIVIDER(TEGRA_CLK_M_KHZ, 1900), &clk_rst->clk_src_uarta);
|
2013-10-10 08:45:07 +02:00
|
|
|
setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_UARTA);
|
|
|
|
udelay(2);
|
|
|
|
clrbits_le32(&clk_rst->rst_dev_l, CLK_L_UARTA);
|
|
|
|
}
|
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
/* Enable output clock (CLK1~3) for external peripherals. */
|
|
|
|
void clock_external_output(int clk_id)
|
|
|
|
{
|
|
|
|
switch (clk_id) {
|
|
|
|
case 1:
|
|
|
|
setbits_le32(&pmc->clk_out_cntrl, 1 << 2);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
setbits_le32(&pmc->clk_out_cntrl, 1 << 10);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
setbits_le32(&pmc->clk_out_cntrl, 1 << 18);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printk(BIOS_CRIT, "ERROR: Unknown output clock id %d\n",
|
|
|
|
clk_id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-19 07:41:34 +01:00
|
|
|
/* Start PLLM for SDRAM. */
|
|
|
|
void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
|
|
|
|
u32 ph135, u32 kvco, u32 kcp, u32 stable_time, u32 emc_source,
|
|
|
|
u32 same_freq)
|
|
|
|
{
|
|
|
|
u32 misc1 = ((setup << PLLM_MISC1_SETUP_SHIFT) |
|
|
|
|
(ph45 << PLLM_MISC1_PD_LSHIFT_PH45_SHIFT) |
|
|
|
|
(ph90 << PLLM_MISC1_PD_LSHIFT_PH90_SHIFT) |
|
|
|
|
(ph135 << PLLM_MISC1_PD_LSHIFT_PH135_SHIFT)),
|
|
|
|
misc2 = ((kvco << PLLM_MISC2_KVCO_SHIFT) |
|
|
|
|
(kcp << PLLM_MISC2_KCP_SHIFT)),
|
|
|
|
base;
|
|
|
|
|
|
|
|
if (same_freq)
|
|
|
|
emc_source |= CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
|
|
|
|
else
|
|
|
|
emc_source &= ~CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note PLLM_BASE.PLLM_OUT1_RSTN must be in RESET_ENABLE mode, and
|
|
|
|
* PLLM_BASE.ENABLE must be in DISABLE state (both are the default
|
|
|
|
* values after coldboot reset).
|
|
|
|
*/
|
|
|
|
|
|
|
|
writel(misc1, &clk_rst->pllm_misc1);
|
|
|
|
writel(misc2, &clk_rst->pllm_misc2);
|
|
|
|
|
|
|
|
/* PLLM.BASE needs BYPASS=0, different from general init_pll */
|
|
|
|
base = readl(&clk_rst->pllm_base);
|
|
|
|
base &= ~(PLLCMX_BASE_DIVN_MASK | PLLCMX_BASE_DIVM_MASK |
|
|
|
|
PLLM_BASE_DIVP_MASK | PLL_BASE_BYPASS);
|
|
|
|
base |= ((m << PLL_BASE_DIVM_SHIFT) | (n << PLL_BASE_DIVN_SHIFT) |
|
|
|
|
(p << PLL_BASE_DIVP_SHIFT));
|
|
|
|
writel(base, &clk_rst->pllm_base);
|
|
|
|
|
|
|
|
setbits_le32(&clk_rst->pllm_base, PLL_BASE_ENABLE);
|
|
|
|
/* stable_time is required, before we can start to check lock. */
|
|
|
|
udelay(stable_time);
|
|
|
|
|
|
|
|
while (!(readl(&clk_rst->pllm_base) & PLL_BASE_LOCK)) {
|
|
|
|
udelay(1);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* After PLLM reports being locked, we have to delay 10us before
|
|
|
|
* enabling PLLM_OUT.
|
|
|
|
*/
|
|
|
|
udelay(10);
|
|
|
|
|
|
|
|
/* Put OUT1 out of reset state (start to output). */
|
|
|
|
setbits_le32(&clk_rst->pllm_out, PLLM_OUT1_RSTN_RESET_DISABLE);
|
|
|
|
|
|
|
|
/* Enable and start MEM(MC) and EMC. */
|
|
|
|
clock_enable_clear_reset(0, CLK_H_MEM | CLK_H_EMC, 0, 0, 0, 0);
|
|
|
|
writel(emc_source, &clk_rst->clk_src_emc);
|
|
|
|
udelay(IO_STABILIZATION_DELAY);
|
|
|
|
}
|
|
|
|
|
2013-10-10 08:45:07 +02:00
|
|
|
void clock_cpu0_config_and_reset(void *entry)
|
|
|
|
{
|
|
|
|
void * const evp_cpu_reset = (uint8_t *)TEGRA_EVP_BASE + 0x100;
|
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
write32(CONFIG_STACK_TOP, &maincpu_stack_pointer);
|
|
|
|
write32((uintptr_t)entry, &maincpu_entry_point);
|
|
|
|
write32((uintptr_t)&maincpu_setup, evp_cpu_reset);
|
|
|
|
|
|
|
|
/* Set active CPU cluster to G */
|
|
|
|
clrbits_le32(&flow->cluster_control, 1);
|
2013-10-10 08:45:07 +02:00
|
|
|
|
|
|
|
// Set up cclk_brst and divider.
|
|
|
|
write32((CRC_CCLK_BRST_POL_PLLX_OUT0 << 0) |
|
|
|
|
(CRC_CCLK_BRST_POL_PLLX_OUT0 << 4) |
|
|
|
|
(CRC_CCLK_BRST_POL_PLLX_OUT0 << 8) |
|
|
|
|
(CRC_CCLK_BRST_POL_PLLX_OUT0 << 12) |
|
|
|
|
(CRC_CCLK_BRST_POL_CPU_STATE_RUN << 28),
|
|
|
|
&clk_rst->cclk_brst_pol);
|
|
|
|
write32(CRC_SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB,
|
|
|
|
&clk_rst->super_cclk_div);
|
|
|
|
|
|
|
|
// Enable the clocks for CPUs 0-3.
|
|
|
|
uint32_t cpu_cmplx_clr = read32(&clk_rst->clk_cpu_cmplx_clr);
|
|
|
|
cpu_cmplx_clr |= CRC_CLK_CLR_CPU0_STP | CRC_CLK_CLR_CPU1_STP |
|
|
|
|
CRC_CLK_CLR_CPU2_STP | CRC_CLK_CLR_CPU3_STP;
|
|
|
|
write32(cpu_cmplx_clr, &clk_rst->clk_cpu_cmplx_clr);
|
|
|
|
|
|
|
|
// Enable other CPU related clocks.
|
|
|
|
setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_CPU);
|
|
|
|
setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_CPUG);
|
2013-12-19 07:41:34 +01:00
|
|
|
setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_CPULP);
|
2013-10-10 08:45:07 +02:00
|
|
|
|
|
|
|
// Disable the reset on the non-CPU parts of the fast cluster.
|
|
|
|
write32(CRC_RST_CPUG_CLR_NONCPU,
|
|
|
|
&clk_rst->rst_cpug_cmplx_clr);
|
|
|
|
// Disable the various resets on the CPUs.
|
|
|
|
write32(CRC_RST_CPUG_CLR_CPU0 | CRC_RST_CPUG_CLR_CPU1 |
|
|
|
|
CRC_RST_CPUG_CLR_CPU2 | CRC_RST_CPUG_CLR_CPU3 |
|
|
|
|
CRC_RST_CPUG_CLR_DBG0 | CRC_RST_CPUG_CLR_DBG1 |
|
|
|
|
CRC_RST_CPUG_CLR_DBG2 | CRC_RST_CPUG_CLR_DBG3 |
|
|
|
|
CRC_RST_CPUG_CLR_CORE0 | CRC_RST_CPUG_CLR_CORE1 |
|
|
|
|
CRC_RST_CPUG_CLR_CORE2 | CRC_RST_CPUG_CLR_CORE3 |
|
|
|
|
CRC_RST_CPUG_CLR_CX0 | CRC_RST_CPUG_CLR_CX1 |
|
|
|
|
CRC_RST_CPUG_CLR_CX2 | CRC_RST_CPUG_CLR_CX3 |
|
|
|
|
CRC_RST_CPUG_CLR_L2 | CRC_RST_CPUG_CLR_PDBG,
|
|
|
|
&clk_rst->rst_cpug_cmplx_clr);
|
2013-12-19 07:41:34 +01:00
|
|
|
|
|
|
|
// Disable the reset on the non-CPU parts of the slow cluster.
|
|
|
|
write32(CRC_RST_CPULP_CLR_NONCPU,
|
|
|
|
&clk_rst->rst_cpulp_cmplx_clr);
|
|
|
|
// Disable the various resets on the LP CPU.
|
|
|
|
write32(CRC_RST_CPULP_CLR_CPU0 | CRC_RST_CPULP_CLR_DBG0 |
|
|
|
|
CRC_RST_CPULP_CLR_CORE0 | CRC_RST_CPULP_CLR_CX0 |
|
|
|
|
CRC_RST_CPULP_CLR_L2 | CRC_RST_CPULP_CLR_PDBG,
|
|
|
|
&clk_rst->rst_cpulp_cmplx_clr);
|
2013-10-10 08:45:07 +02:00
|
|
|
}
|
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
void clock_halt_avp(void)
|
|
|
|
{
|
|
|
|
for (;;) {
|
|
|
|
write32(FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ |
|
|
|
|
FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT,
|
|
|
|
&flow->halt_cop_events);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-10 08:45:07 +02:00
|
|
|
void clock_init(void)
|
Tegra,Tegra124: proposed layout for file hierarchy with example
This change shows the source structure for nvidia Tegra and Tegra124
SOC. The problem we are trying to solve is that there is a large
amount of common code in the form of .c and .h files across many
different Tegra SOCs. The solution is to provide common code in a
single directory, but not to compile in the common code directory;
rather, we compile in a directory for a given SOC. Different SOCs
will sometimes need different bits of code from the common directory.
Tegra common code lives in tegra/, but there is no makefile there: if
a Tegra common file is needed in a SOC, it is referenced via a
Makefile in a specific Tegra SOC.
Another issue is includes. Include files in the common directory might be
accessed by a piece of code in an SOC directory. More problematically,
code in the common directory might require a file in an SOC directory.
We don't want to put the SOC name in an #include path, e.g.
in a C file in tegra/ is very undesirable, since we might be compiling
for a tegra114.
On some systems this is solved by a pre-pass which creates a set of
symbolic links; on others with nested #ifdef in the common code
which include different .h files depending on CPP variables.
In previous years, both LinuxBIOS and coreboot have tried these
solutions and found them inconvenient and error-prone.
We choose to solve it by requiring explicit naming of part of the path
of files that are in the common directory. This requirement, coupled
with two -I directives in the Makefile.inc, allows common and SOC
C code to incorporate both common and SOC .h files.
.c and .h files -- SOC or common -- name include
files in the common directory with the prefix tegra/, e.g.
SOC files will be included from the SOC directory if they have no prefix:
The full patch of clock.h will depend on what SOC is being compiled, which
is desirable.
In this way, a common file can pick up a specific SOC file without
creating symlinks or other such tricky magic.
We show this usage with one file, soc/nvidia/tega124/clock.c. This compiles.
The last question is where to put the prototype for the function
defined in this file -- soc.h?
Change-Id: Iecb635cec70f24a5b3e18caeda09d04a00d29409
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: https://chromium-review.googlesource.com/171569
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 53e3bed868953f3da588ec90661d316a6482e27e)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6621
Tested-by: build bot (Jenkins)
2013-10-04 02:05:55 +02:00
|
|
|
{
|
2013-10-10 08:45:07 +02:00
|
|
|
u32 osc = clock_get_osc_bits();
|
Tegra,Tegra124: proposed layout for file hierarchy with example
This change shows the source structure for nvidia Tegra and Tegra124
SOC. The problem we are trying to solve is that there is a large
amount of common code in the form of .c and .h files across many
different Tegra SOCs. The solution is to provide common code in a
single directory, but not to compile in the common code directory;
rather, we compile in a directory for a given SOC. Different SOCs
will sometimes need different bits of code from the common directory.
Tegra common code lives in tegra/, but there is no makefile there: if
a Tegra common file is needed in a SOC, it is referenced via a
Makefile in a specific Tegra SOC.
Another issue is includes. Include files in the common directory might be
accessed by a piece of code in an SOC directory. More problematically,
code in the common directory might require a file in an SOC directory.
We don't want to put the SOC name in an #include path, e.g.
in a C file in tegra/ is very undesirable, since we might be compiling
for a tegra114.
On some systems this is solved by a pre-pass which creates a set of
symbolic links; on others with nested #ifdef in the common code
which include different .h files depending on CPP variables.
In previous years, both LinuxBIOS and coreboot have tried these
solutions and found them inconvenient and error-prone.
We choose to solve it by requiring explicit naming of part of the path
of files that are in the common directory. This requirement, coupled
with two -I directives in the Makefile.inc, allows common and SOC
C code to incorporate both common and SOC .h files.
.c and .h files -- SOC or common -- name include
files in the common directory with the prefix tegra/, e.g.
SOC files will be included from the SOC directory if they have no prefix:
The full patch of clock.h will depend on what SOC is being compiled, which
is desirable.
In this way, a common file can pick up a specific SOC file without
creating symlinks or other such tricky magic.
We show this usage with one file, soc/nvidia/tega124/clock.c. This compiles.
The last question is where to put the prototype for the function
defined in this file -- soc.h?
Change-Id: Iecb635cec70f24a5b3e18caeda09d04a00d29409
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: https://chromium-review.googlesource.com/171569
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 53e3bed868953f3da588ec90661d316a6482e27e)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6621
Tested-by: build bot (Jenkins)
2013-10-04 02:05:55 +02:00
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
/* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */
|
|
|
|
writel(0x2b << 17 | 0xb << 9, &clk_rst->pllc_misc2);
|
2013-10-10 08:45:07 +02:00
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
/* Max out the AVP clock before everything else (need PLLC for that). */
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc,
|
|
|
|
osc_table[osc].pllc, PLLC_MISC_LOCK_ENABLE);
|
2013-10-26 02:49:26 +02:00
|
|
|
|
|
|
|
/* Typical ratios are 1:2:2 or 1:2:3 sclk:hclk:pclk (See: APB DMA
|
|
|
|
* features section in the TRM). */
|
|
|
|
write32(1 << HCLK_DIVISOR_SHIFT | 0 << PCLK_DIVISOR_SHIFT,
|
|
|
|
&clk_rst->clk_sys_rate); /* pclk = hclk = sclk/2 */
|
2013-12-19 07:41:34 +01:00
|
|
|
write32(CLK_DIVIDER(TEGRA_PLLC_KHZ, 300000) << PLL_OUT_RATIO_SHIFT |
|
|
|
|
PLL_OUT_CLKEN | PLL_OUT_RSTN, &clk_rst->pllc_out);
|
2013-10-26 02:49:26 +02:00
|
|
|
write32(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT |
|
2013-12-19 07:41:34 +01:00
|
|
|
SCLK_SOURCE_PLLC_OUT1 << SCLK_RUN_SHIFT,
|
2013-10-26 02:49:26 +02:00
|
|
|
&clk_rst->sclk_brst_pol); /* sclk = 300 MHz */
|
|
|
|
|
|
|
|
/* Change the oscillator drive strength (from U-Boot -- why?) */
|
|
|
|
clrsetbits_le32(&clk_rst->osc_ctrl, OSC_XOFS_MASK,
|
|
|
|
OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
|
2013-10-10 08:45:07 +02:00
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
/*
|
|
|
|
* Ambiguous quote from u-boot. TODO: what's this mean?
|
2013-10-10 08:45:07 +02:00
|
|
|
* "should update same value in PMC_OSC_EDPD_OVER XOFS
|
2013-10-26 02:49:26 +02:00
|
|
|
* field for warmboot "
|
|
|
|
*/
|
|
|
|
clrsetbits_le32(&pmc->osc_edpd_over, PMC_OSC_EDPD_OVER_XOFS_MASK,
|
|
|
|
OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT);
|
2013-10-10 08:45:07 +02:00
|
|
|
|
|
|
|
/* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */
|
2013-10-26 02:49:26 +02:00
|
|
|
clrbits_le32(&clk_rst->pllx_misc3, PLLX_IDDQ_MASK);
|
|
|
|
|
|
|
|
/* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */
|
|
|
|
write32((CLK_DIVIDER(TEGRA_PLLP_KHZ, 9600) << PLL_OUT_RATIO_SHIFT |
|
|
|
|
PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT1_SHIFT |
|
|
|
|
(CLK_DIVIDER(TEGRA_PLLP_KHZ, 48000) << PLL_OUT_RATIO_SHIFT |
|
|
|
|
PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT2_SHIFT,
|
|
|
|
&clk_rst->pllp_outa);
|
|
|
|
write32((CLK_DIVIDER(TEGRA_PLLP_KHZ, 102000) << PLL_OUT_RATIO_SHIFT |
|
|
|
|
PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT3_SHIFT |
|
|
|
|
(CLK_DIVIDER(TEGRA_PLLP_KHZ, 204000) << PLL_OUT_RATIO_SHIFT |
|
|
|
|
PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT4_SHIFT,
|
|
|
|
&clk_rst->pllp_outb);
|
2013-10-10 08:45:07 +02:00
|
|
|
|
t124: nyan: Enable lock bit on pll
A PLL (Phase-Locked Loop) clock must be locked before it is assigned
as clock source. Otherwise, this clock is unreliable.
Before:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 40009e01, misc(600060e4): 00000000
p base(600060a0): 40002201, misc(600060ac): 00000200
u base(600060c0): 40005001, misc(600060cc): 00000300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
After:
c base(60006080): 48003201, misc(6000608c): 03000000
x base(600060e0): 48009e01, misc(600060e4): 00040000
p base(600060a0): 5801980c, misc(600060ac): 00040800
u base(600060c0): 48005001, misc(600060cc): 00400300
d base(600060d0): 48011b0c, misc(600060dc): 40400800
dp base(60006590): 58305a01, misc(60006594): 40000000
BUG=None
TEST=build nyan and boot
Original-Change-Id: I7e5a2eeb5b17f761e0c462ec68a8b221f327fedc
Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/188447
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 7e8e2854b2b7d1ed20d74891c3d19b6c3dd41c55)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ief9efa6937af26fe1a10a7b360fc2f5477416b97
Reviewed-on: http://review.coreboot.org/7414
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2014-03-01 02:35:48 +01:00
|
|
|
/* init pllx */
|
|
|
|
init_pll(&clk_rst->pllx_base, &clk_rst->pllx_misc,
|
|
|
|
osc_table[osc].pllx, PLLPAXS_MISC_LOCK_ENABLE);
|
|
|
|
|
|
|
|
/* init pllu */
|
|
|
|
init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc,
|
|
|
|
osc_table[osc].pllu, PLLUD_MISC_LOCK_ENABLE);
|
|
|
|
|
2013-10-21 15:43:03 +02:00
|
|
|
init_utmip_pll();
|
2013-10-26 02:49:26 +02:00
|
|
|
graphics_pll();
|
2013-10-10 08:45:07 +02:00
|
|
|
}
|
|
|
|
|
2013-10-26 02:49:26 +02:00
|
|
|
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x)
|
2013-10-10 08:45:07 +02:00
|
|
|
{
|
2013-10-21 15:43:03 +02:00
|
|
|
if (l) writel(l, &clk_rst->clk_enb_l_set);
|
|
|
|
if (h) writel(h, &clk_rst->clk_enb_h_set);
|
|
|
|
if (u) writel(u, &clk_rst->clk_enb_u_set);
|
|
|
|
if (v) writel(v, &clk_rst->clk_enb_v_set);
|
|
|
|
if (w) writel(w, &clk_rst->clk_enb_w_set);
|
2013-10-26 02:49:26 +02:00
|
|
|
if (x) writel(x, &clk_rst->clk_enb_x_set);
|
2013-10-10 08:45:07 +02:00
|
|
|
|
2013-10-21 15:43:03 +02:00
|
|
|
/* Give clocks time to stabilize. */
|
2013-10-10 08:45:07 +02:00
|
|
|
udelay(IO_STABILIZATION_DELAY);
|
|
|
|
|
2013-10-21 15:43:03 +02:00
|
|
|
if (l) writel(l, &clk_rst->rst_dev_l_clr);
|
|
|
|
if (h) writel(h, &clk_rst->rst_dev_h_clr);
|
|
|
|
if (u) writel(u, &clk_rst->rst_dev_u_clr);
|
|
|
|
if (v) writel(v, &clk_rst->rst_dev_v_clr);
|
|
|
|
if (w) writel(w, &clk_rst->rst_dev_w_clr);
|
2013-10-26 02:49:26 +02:00
|
|
|
if (x) writel(x, &clk_rst->rst_dev_x_clr);
|
Tegra,Tegra124: proposed layout for file hierarchy with example
This change shows the source structure for nvidia Tegra and Tegra124
SOC. The problem we are trying to solve is that there is a large
amount of common code in the form of .c and .h files across many
different Tegra SOCs. The solution is to provide common code in a
single directory, but not to compile in the common code directory;
rather, we compile in a directory for a given SOC. Different SOCs
will sometimes need different bits of code from the common directory.
Tegra common code lives in tegra/, but there is no makefile there: if
a Tegra common file is needed in a SOC, it is referenced via a
Makefile in a specific Tegra SOC.
Another issue is includes. Include files in the common directory might be
accessed by a piece of code in an SOC directory. More problematically,
code in the common directory might require a file in an SOC directory.
We don't want to put the SOC name in an #include path, e.g.
in a C file in tegra/ is very undesirable, since we might be compiling
for a tegra114.
On some systems this is solved by a pre-pass which creates a set of
symbolic links; on others with nested #ifdef in the common code
which include different .h files depending on CPP variables.
In previous years, both LinuxBIOS and coreboot have tried these
solutions and found them inconvenient and error-prone.
We choose to solve it by requiring explicit naming of part of the path
of files that are in the common directory. This requirement, coupled
with two -I directives in the Makefile.inc, allows common and SOC
C code to incorporate both common and SOC .h files.
.c and .h files -- SOC or common -- name include
files in the common directory with the prefix tegra/, e.g.
SOC files will be included from the SOC directory if they have no prefix:
The full patch of clock.h will depend on what SOC is being compiled, which
is desirable.
In this way, a common file can pick up a specific SOC file without
creating symlinks or other such tricky magic.
We show this usage with one file, soc/nvidia/tega124/clock.c. This compiles.
The last question is where to put the prototype for the function
defined in this file -- soc.h?
Change-Id: Iecb635cec70f24a5b3e18caeda09d04a00d29409
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: https://chromium-review.googlesource.com/171569
Reviewed-by: Ronald Minnich <rminnich@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 53e3bed868953f3da588ec90661d316a6482e27e)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6621
Tested-by: build bot (Jenkins)
2013-10-04 02:05:55 +02:00
|
|
|
}
|
2014-03-27 05:29:45 +01:00
|
|
|
|
|
|
|
void clock_reset_l(u32 bit)
|
|
|
|
{
|
|
|
|
writel(bit, &clk_rst->rst_dev_l_set);
|
|
|
|
udelay(1);
|
|
|
|
writel(bit, &clk_rst->rst_dev_l_clr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clock_reset_h(u32 bit)
|
|
|
|
{
|
|
|
|
writel(bit, &clk_rst->rst_dev_h_set);
|
|
|
|
udelay(1);
|
|
|
|
writel(bit, &clk_rst->rst_dev_h_clr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clock_reset_u(u32 bit)
|
|
|
|
{
|
|
|
|
writel(bit, &clk_rst->rst_dev_u_set);
|
|
|
|
udelay(1);
|
|
|
|
writel(bit, &clk_rst->rst_dev_u_clr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clock_reset_v(u32 bit)
|
|
|
|
{
|
|
|
|
writel(bit, &clk_rst->rst_dev_v_set);
|
|
|
|
udelay(1);
|
|
|
|
writel(bit, &clk_rst->rst_dev_v_clr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clock_reset_w(u32 bit)
|
|
|
|
{
|
|
|
|
writel(bit, &clk_rst->rst_dev_w_set);
|
|
|
|
udelay(1);
|
|
|
|
writel(bit, &clk_rst->rst_dev_w_clr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clock_reset_x(u32 bit)
|
|
|
|
{
|
|
|
|
writel(bit, &clk_rst->rst_dev_x_set);
|
|
|
|
udelay(1);
|
|
|
|
writel(bit, &clk_rst->rst_dev_x_clr);
|
|
|
|
}
|