[PATCH 1/3] [ARM] tegra: add PCI Express clocks
Mike Rapoport
mike at compulab.co.il
Sun Sep 19 03:52:44 EDT 2010
Mogambo Park wrote:
> Good evening Mike Rapport,
>
> Are there is some datasheet/TRM availability for Nvidia Tegra chip ?
> Please say me if yes and where.
The Tegra docs are available only under NDA.
>
> thanks
>
> On Fri, Sep 17, 2010 at 1:53 AM, Mike Rapoport <mike at compulab.co.il> wrote:
>> Signed-off-by: Mike Rapoport <mike at compulab.co.il>
>> ---
>> arch/arm/mach-tegra/tegra2_clocks.c | 76 +++++++++++++++++++++++++++++++++-
>> 1 files changed, 73 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
>> index 4261632..44f1b81 100644
>> --- a/arch/arm/mach-tegra/tegra2_clocks.c
>> +++ b/arch/arm/mach-tegra/tegra2_clocks.c
>> @@ -92,6 +92,8 @@
>> #define PLLD_MISC_DIV_RST (1<<23)
>> #define PLLD_MISC_DCCON_SHIFT 12
>>
>> +#define PLLE_MISC_READY (1 << 15)
>> +
>> #define PERIPH_CLK_TO_ENB_REG(c) ((c->clk_num / 32) * 4)
>> #define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->clk_num / 32) * 8)
>> #define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->clk_num % 32))
>> @@ -356,12 +358,12 @@ static unsigned long tegra2_pll_clk_recalculate_rate(struct clk *c)
>> return c->rate;
>> }
>>
>> -static int tegra2_pll_clk_wait_for_lock(struct clk *c)
>> +static int tegra2_pll_clk_wait_for_bit_set(struct clk *c, int bit)
>> {
>> ktime_t before;
>>
>> before = ktime_get();
>> - while (!(clk_readl(c->reg + PLL_BASE) & PLL_BASE_LOCK)) {
>> + while (!(clk_readl(c->reg + PLL_BASE) & bit)) {
>> if (ktime_us_delta(ktime_get(), before) > 5000) {
>> pr_err("Timed out waiting for lock bit on pll %s",
>> c->name);
>> @@ -414,7 +416,7 @@ static int tegra2_pll_clk_enable(struct clk *c)
>> val |= PLL_MISC_LOCK_ENABLE;
>> clk_writel(val, c->reg + PLL_MISC(c));
>>
>> - tegra2_pll_clk_wait_for_lock(c);
>> + tegra2_pll_clk_wait_for_bit_set(c, PLL_BASE_LOCK);
>>
>> return 0;
>> }
>> @@ -754,6 +756,34 @@ static struct clk_ops tegra_clk_double_ops = {
>> .recalculate_rate = &tegra2_clk_recalculate_rate,
>> };
>>
>> +/* PCI Express clock ops */
>> +static int tegra2_plle_clk_enable(struct clk *c)
>> +{
>> + u32 val;
>> +
>> + pr_debug("%s on clock %s\n", __func__, c->name);
>> +
>> + if (tegra2_pll_clk_wait_for_bit_set(c, PLLE_MISC_READY))
>> + return -EBUSY;
>> +
>> + val = clk_readl(c->reg + PLL_BASE);
>> + val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
>> + clk_writel(val, c->reg + PLL_BASE);
>> +
>> + return 0;
>> +}
>> +
>> +static struct clk_ops tegra_plle_ops = {
>> + .init = tegra2_pll_clk_init,
>> + .enable = tegra2_plle_clk_enable,
>> + .set_rate = tegra2_pll_clk_set_rate,
>> +};
>> +
>> +static struct clk_ops tegra_pcie_clk_ops = {
>> + .enable = tegra2_periph_clk_enable,
>> + .disable = tegra2_periph_clk_disable,
>> +};
>> +
>> /* Clock definitions */
>> static struct clk tegra_clk_32k = {
>> .name = "clk_32k",
>> @@ -1109,6 +1139,42 @@ static struct clk tegra_clk_pclk = {
>> .ops = &tegra_bus_ops,
>> };
>>
>> +/* PCI Express clocks */
>> +static struct clk_pll_table tegra_pll_e_table[] = {
>> + { 12000000, 100000000, 200, 24, 1, 0 },
>> +};
>> +
>> +static struct clk tegra_pll_e = {
>> + .name = "pll_e",
>> + .flags = PLL_ALT_MISC_REG,
>> + .ops = &tegra_plle_ops,
>> + .input_min = 12000000,
>> + .input_max = 12000000,
>> + .parent = &tegra_clk_m,
>> + .reg = 0xe8,
>> + .pll_table = tegra_pll_e_table,
>> +};
>> +
>> +static struct clk tegra_clk_pex = {
>> + .name = "pex",
>> + .flags = PERIPH_MANUAL_RESET,
>> + .ops = &tegra_pcie_clk_ops,
>> + .clk_num = 70,
>> +};
>> +
>> +static struct clk tegra_clk_afi = {
>> + .name = "afi",
>> + .flags = PERIPH_MANUAL_RESET,
>> + .ops = &tegra_pcie_clk_ops,
>> + .clk_num = 72,
>> +};
>> +
>> +/* the pcie_xclk is required for reset of PCIE subsystem */
>> +static struct clk tegra_clk_pcie_xclk = {
>> + .name = "pcie_xclk",
>> + .clk_num = 74,
>> +};
>> +
>> static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
>> { .input = &tegra_pll_m, .value = 0},
>> { .input = &tegra_pll_c, .value = 1},
>> @@ -1315,11 +1381,15 @@ struct clk_lookup tegra_clk_lookups[] = {
>> CLK(NULL, "pll_d_out0", &tegra_pll_d_out0),
>> CLK(NULL, "pll_u", &tegra_pll_u),
>> CLK(NULL, "pll_x", &tegra_pll_x),
>> + CLK(NULL, "pll_e", &tegra_pll_e),
>> CLK(NULL, "cpu", &tegra_clk_cpu),
>> CLK(NULL, "sys", &tegra_clk_sys),
>> CLK(NULL, "hclk", &tegra_clk_hclk),
>> CLK(NULL, "pclk", &tegra_clk_pclk),
>> CLK(NULL, "clk_d", &tegra_clk_d),
>> + CLK(NULL, "pcie_xclk", &tegra_clk_pcie_xclk),
>> + CLK(NULL, "pex", &tegra_clk_pex),
>> + CLK(NULL, "afi", &tegra_clk_afi),
>> };
>>
>> void __init tegra2_init_clocks(void)
>> --
>> 1.6.6.2
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
--
Sincerely yours,
Mike.
More information about the linux-arm-kernel
mailing list