aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/tegra/clk-tegra210.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/tegra/clk-tegra210.c')
-rw-r--r--drivers/clk/tegra/clk-tegra210.c361
1 files changed, 357 insertions, 4 deletions
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 9e6260869eb9..9fb5d51ccce4 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -22,10 +22,12 @@
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <linux/mutex.h>
25#include <linux/clk/tegra.h> 26#include <linux/clk/tegra.h>
26#include <dt-bindings/clock/tegra210-car.h> 27#include <dt-bindings/clock/tegra210-car.h>
27#include <dt-bindings/reset/tegra210-car.h> 28#include <dt-bindings/reset/tegra210-car.h>
28#include <linux/iopoll.h> 29#include <linux/iopoll.h>
30#include <soc/tegra/pmc.h>
29 31
30#include "clk.h" 32#include "clk.h"
31#include "clk-id.h" 33#include "clk-id.h"
@@ -41,6 +43,7 @@
41#define CLK_SOURCE_CSITE 0x1d4 43#define CLK_SOURCE_CSITE 0x1d4
42#define CLK_SOURCE_EMC 0x19c 44#define CLK_SOURCE_EMC 0x19c
43#define CLK_SOURCE_SOR1 0x410 45#define CLK_SOURCE_SOR1 0x410
46#define CLK_SOURCE_LA 0x1f8
44 47
45#define PLLC_BASE 0x80 48#define PLLC_BASE 0x80
46#define PLLC_OUT 0x84 49#define PLLC_OUT 0x84
@@ -231,6 +234,30 @@
231#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 234#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
232#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac 235#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
233 236
237#define LVL2_CLK_GATE_OVRA 0xf8
238#define LVL2_CLK_GATE_OVRC 0x3a0
239#define LVL2_CLK_GATE_OVRD 0x3a4
240#define LVL2_CLK_GATE_OVRE 0x554
241
242/* I2S registers to handle during APE MBIST WAR */
243#define TEGRA210_I2S_BASE 0x1000
244#define TEGRA210_I2S_SIZE 0x100
245#define TEGRA210_I2S_CTRLS 5
246#define TEGRA210_I2S_CG 0x88
247#define TEGRA210_I2S_CTRL 0xa0
248
249/* DISPA registers to handle during MBIST WAR */
250#define DC_CMD_DISPLAY_COMMAND 0xc8
251#define DC_COM_DSC_TOP_CTL 0xcf8
252
253/* VIC register to handle during MBIST WAR */
254#define NV_PVIC_THI_SLCG_OVERRIDE_LOW 0x8c
255
256/* APE, DISPA and VIC base addesses needed for MBIST WAR */
257#define TEGRA210_AHUB_BASE 0x702d0000
258#define TEGRA210_DISPA_BASE 0x54200000
259#define TEGRA210_VIC_BASE 0x54340000
260
234/* 261/*
235 * SDM fractional divisor is 16-bit 2's complement signed number within 262 * SDM fractional divisor is 16-bit 2's complement signed number within
236 * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned 263 * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned
@@ -255,8 +282,22 @@ static struct cpu_clk_suspend_context {
255} tegra210_cpu_clk_sctx; 282} tegra210_cpu_clk_sctx;
256#endif 283#endif
257 284
285struct tegra210_domain_mbist_war {
286 void (*handle_lvl2_ovr)(struct tegra210_domain_mbist_war *mbist);
287 const u32 lvl2_offset;
288 const u32 lvl2_mask;
289 const unsigned int num_clks;
290 const unsigned int *clk_init_data;
291 struct clk_bulk_data *clks;
292};
293
294static struct clk **clks;
295
258static void __iomem *clk_base; 296static void __iomem *clk_base;
259static void __iomem *pmc_base; 297static void __iomem *pmc_base;
298static void __iomem *ahub_base;
299static void __iomem *dispa_base;
300static void __iomem *vic_base;
260 301
261static unsigned long osc_freq; 302static unsigned long osc_freq;
262static unsigned long pll_ref_freq; 303static unsigned long pll_ref_freq;
@@ -267,6 +308,7 @@ static DEFINE_SPINLOCK(pll_re_lock);
267static DEFINE_SPINLOCK(pll_u_lock); 308static DEFINE_SPINLOCK(pll_u_lock);
268static DEFINE_SPINLOCK(sor1_lock); 309static DEFINE_SPINLOCK(sor1_lock);
269static DEFINE_SPINLOCK(emc_lock); 310static DEFINE_SPINLOCK(emc_lock);
311static DEFINE_MUTEX(lvl2_ovr_lock);
270 312
271/* possible OSC frequencies in Hz */ 313/* possible OSC frequencies in Hz */
272static unsigned long tegra210_input_freq[] = { 314static unsigned long tegra210_input_freq[] = {
@@ -310,6 +352,8 @@ static const char *mux_pllmcp_clkm[] = {
310#define PLLA_MISC2_WRITE_MASK 0x06ffffff 352#define PLLA_MISC2_WRITE_MASK 0x06ffffff
311 353
312/* PLLD */ 354/* PLLD */
355#define PLLD_BASE_CSI_CLKSOURCE (1 << 23)
356
313#define PLLD_MISC0_EN_SDM (1 << 16) 357#define PLLD_MISC0_EN_SDM (1 << 16)
314#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17) 358#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17)
315#define PLLD_MISC0_LOCK_ENABLE (1 << 18) 359#define PLLD_MISC0_LOCK_ENABLE (1 << 18)
@@ -513,6 +557,115 @@ void tegra210_set_sata_pll_seq_sw(bool state)
513} 557}
514EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); 558EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw);
515 559
560static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist)
561{
562 u32 val;
563
564 val = readl_relaxed(clk_base + mbist->lvl2_offset);
565 writel_relaxed(val | mbist->lvl2_mask, clk_base + mbist->lvl2_offset);
566 fence_udelay(1, clk_base);
567 writel_relaxed(val, clk_base + mbist->lvl2_offset);
568 fence_udelay(1, clk_base);
569}
570
571static void tegra210_venc_mbist_war(struct tegra210_domain_mbist_war *mbist)
572{
573 u32 csi_src, ovra, ovre;
574 unsigned long flags = 0;
575
576 spin_lock_irqsave(&pll_d_lock, flags);
577
578 csi_src = readl_relaxed(clk_base + PLLD_BASE);
579 writel_relaxed(csi_src | PLLD_BASE_CSI_CLKSOURCE, clk_base + PLLD_BASE);
580 fence_udelay(1, clk_base);
581
582 ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA);
583 writel_relaxed(ovra | BIT(15), clk_base + LVL2_CLK_GATE_OVRA);
584 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
585 writel_relaxed(ovre | BIT(3), clk_base + LVL2_CLK_GATE_OVRE);
586 fence_udelay(1, clk_base);
587
588 writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA);
589 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
590 writel_relaxed(csi_src, clk_base + PLLD_BASE);
591 fence_udelay(1, clk_base);
592
593 spin_unlock_irqrestore(&pll_d_lock, flags);
594}
595
596static void tegra210_disp_mbist_war(struct tegra210_domain_mbist_war *mbist)
597{
598 u32 ovra, dsc_top_ctrl;
599
600 ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA);
601 writel_relaxed(ovra | BIT(1), clk_base + LVL2_CLK_GATE_OVRA);
602 fence_udelay(1, clk_base);
603
604 dsc_top_ctrl = readl_relaxed(dispa_base + DC_COM_DSC_TOP_CTL);
605 writel_relaxed(dsc_top_ctrl | BIT(2), dispa_base + DC_COM_DSC_TOP_CTL);
606 readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND);
607 writel_relaxed(dsc_top_ctrl, dispa_base + DC_COM_DSC_TOP_CTL);
608 readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND);
609
610 writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA);
611 fence_udelay(1, clk_base);
612}
613
614static void tegra210_vic_mbist_war(struct tegra210_domain_mbist_war *mbist)
615{
616 u32 ovre, val;
617
618 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
619 writel_relaxed(ovre | BIT(5), clk_base + LVL2_CLK_GATE_OVRE);
620 fence_udelay(1, clk_base);
621
622 val = readl_relaxed(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
623 writel_relaxed(val | BIT(0) | GENMASK(7, 2) | BIT(24),
624 vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
625 fence_udelay(1, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
626
627 writel_relaxed(val, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
628 readl(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
629
630 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
631 fence_udelay(1, clk_base);
632}
633
634static void tegra210_ape_mbist_war(struct tegra210_domain_mbist_war *mbist)
635{
636 void __iomem *i2s_base;
637 unsigned int i;
638 u32 ovrc, ovre;
639
640 ovrc = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRC);
641 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
642 writel_relaxed(ovrc | BIT(1), clk_base + LVL2_CLK_GATE_OVRC);
643 writel_relaxed(ovre | BIT(10) | BIT(11),
644 clk_base + LVL2_CLK_GATE_OVRE);
645 fence_udelay(1, clk_base);
646
647 i2s_base = ahub_base + TEGRA210_I2S_BASE;
648
649 for (i = 0; i < TEGRA210_I2S_CTRLS; i++) {
650 u32 i2s_ctrl;
651
652 i2s_ctrl = readl_relaxed(i2s_base + TEGRA210_I2S_CTRL);
653 writel_relaxed(i2s_ctrl | BIT(10),
654 i2s_base + TEGRA210_I2S_CTRL);
655 writel_relaxed(0, i2s_base + TEGRA210_I2S_CG);
656 readl(i2s_base + TEGRA210_I2S_CG);
657 writel_relaxed(1, i2s_base + TEGRA210_I2S_CG);
658 writel_relaxed(i2s_ctrl, i2s_base + TEGRA210_I2S_CTRL);
659 readl(i2s_base + TEGRA210_I2S_CTRL);
660
661 i2s_base += TEGRA210_I2S_SIZE;
662 }
663
664 writel_relaxed(ovrc, clk_base + LVL2_CLK_GATE_OVRC);
665 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
666 fence_udelay(1, clk_base);
667}
668
516static inline void _pll_misc_chk_default(void __iomem *base, 669static inline void _pll_misc_chk_default(void __iomem *base,
517 struct tegra_clk_pll_params *params, 670 struct tegra_clk_pll_params *params,
518 u8 misc_num, u32 default_val, u32 mask) 671 u8 misc_num, u32 default_val, u32 mask)
@@ -2411,13 +2564,150 @@ static struct tegra_audio_clk_info tegra210_audio_plls[] = {
2411 { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" }, 2564 { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" },
2412}; 2565};
2413 2566
2414static struct clk **clks;
2415
2416static const char * const aclk_parents[] = { 2567static const char * const aclk_parents[] = {
2417 "pll_a1", "pll_c", "pll_p", "pll_a_out0", "pll_c2", "pll_c3", 2568 "pll_a1", "pll_c", "pll_p", "pll_a_out0", "pll_c2", "pll_c3",
2418 "clk_m" 2569 "clk_m"
2419}; 2570};
2420 2571
2572static const unsigned int nvjpg_slcg_clkids[] = { TEGRA210_CLK_NVDEC };
2573static const unsigned int nvdec_slcg_clkids[] = { TEGRA210_CLK_NVJPG };
2574static const unsigned int sor_slcg_clkids[] = { TEGRA210_CLK_HDA2CODEC_2X,
2575 TEGRA210_CLK_HDA2HDMI, TEGRA210_CLK_DISP1, TEGRA210_CLK_DISP2 };
2576static const unsigned int disp_slcg_clkids[] = { TEGRA210_CLK_LA,
2577 TEGRA210_CLK_HOST1X};
2578static const unsigned int xusba_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST,
2579 TEGRA210_CLK_XUSB_DEV };
2580static const unsigned int xusbb_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST,
2581 TEGRA210_CLK_XUSB_SS };
2582static const unsigned int xusbc_slcg_clkids[] = { TEGRA210_CLK_XUSB_DEV,
2583 TEGRA210_CLK_XUSB_SS };
2584static const unsigned int venc_slcg_clkids[] = { TEGRA210_CLK_HOST1X,
2585 TEGRA210_CLK_PLL_D };
2586static const unsigned int ape_slcg_clkids[] = { TEGRA210_CLK_ACLK,
2587 TEGRA210_CLK_I2S0, TEGRA210_CLK_I2S1, TEGRA210_CLK_I2S2,
2588 TEGRA210_CLK_I2S3, TEGRA210_CLK_I2S4, TEGRA210_CLK_SPDIF_OUT,
2589 TEGRA210_CLK_D_AUDIO };
2590static const unsigned int vic_slcg_clkids[] = { TEGRA210_CLK_HOST1X };
2591
2592static struct tegra210_domain_mbist_war tegra210_pg_mbist_war[] = {
2593 [TEGRA_POWERGATE_VENC] = {
2594 .handle_lvl2_ovr = tegra210_venc_mbist_war,
2595 .num_clks = ARRAY_SIZE(venc_slcg_clkids),
2596 .clk_init_data = venc_slcg_clkids,
2597 },
2598 [TEGRA_POWERGATE_SATA] = {
2599 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2600 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2601 .lvl2_mask = BIT(0) | BIT(17) | BIT(19),
2602 },
2603 [TEGRA_POWERGATE_MPE] = {
2604 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2605 .lvl2_offset = LVL2_CLK_GATE_OVRE,
2606 .lvl2_mask = BIT(2),
2607 },
2608 [TEGRA_POWERGATE_SOR] = {
2609 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2610 .num_clks = ARRAY_SIZE(sor_slcg_clkids),
2611 .clk_init_data = sor_slcg_clkids,
2612 .lvl2_offset = LVL2_CLK_GATE_OVRA,
2613 .lvl2_mask = BIT(1) | BIT(2),
2614 },
2615 [TEGRA_POWERGATE_DIS] = {
2616 .handle_lvl2_ovr = tegra210_disp_mbist_war,
2617 .num_clks = ARRAY_SIZE(disp_slcg_clkids),
2618 .clk_init_data = disp_slcg_clkids,
2619 },
2620 [TEGRA_POWERGATE_DISB] = {
2621 .num_clks = ARRAY_SIZE(disp_slcg_clkids),
2622 .clk_init_data = disp_slcg_clkids,
2623 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2624 .lvl2_offset = LVL2_CLK_GATE_OVRA,
2625 .lvl2_mask = BIT(2),
2626 },
2627 [TEGRA_POWERGATE_XUSBA] = {
2628 .num_clks = ARRAY_SIZE(xusba_slcg_clkids),
2629 .clk_init_data = xusba_slcg_clkids,
2630 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2631 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2632 .lvl2_mask = BIT(30) | BIT(31),
2633 },
2634 [TEGRA_POWERGATE_XUSBB] = {
2635 .num_clks = ARRAY_SIZE(xusbb_slcg_clkids),
2636 .clk_init_data = xusbb_slcg_clkids,
2637 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2638 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2639 .lvl2_mask = BIT(30) | BIT(31),
2640 },
2641 [TEGRA_POWERGATE_XUSBC] = {
2642 .num_clks = ARRAY_SIZE(xusbc_slcg_clkids),
2643 .clk_init_data = xusbc_slcg_clkids,
2644 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2645 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2646 .lvl2_mask = BIT(30) | BIT(31),
2647 },
2648 [TEGRA_POWERGATE_VIC] = {
2649 .num_clks = ARRAY_SIZE(vic_slcg_clkids),
2650 .clk_init_data = vic_slcg_clkids,
2651 .handle_lvl2_ovr = tegra210_vic_mbist_war,
2652 },
2653 [TEGRA_POWERGATE_NVDEC] = {
2654 .num_clks = ARRAY_SIZE(nvdec_slcg_clkids),
2655 .clk_init_data = nvdec_slcg_clkids,
2656 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2657 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2658 .lvl2_mask = BIT(9) | BIT(31),
2659 },
2660 [TEGRA_POWERGATE_NVJPG] = {
2661 .num_clks = ARRAY_SIZE(nvjpg_slcg_clkids),
2662 .clk_init_data = nvjpg_slcg_clkids,
2663 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2664 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2665 .lvl2_mask = BIT(9) | BIT(31),
2666 },
2667 [TEGRA_POWERGATE_AUD] = {
2668 .num_clks = ARRAY_SIZE(ape_slcg_clkids),
2669 .clk_init_data = ape_slcg_clkids,
2670 .handle_lvl2_ovr = tegra210_ape_mbist_war,
2671 },
2672 [TEGRA_POWERGATE_VE2] = {
2673 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2674 .lvl2_offset = LVL2_CLK_GATE_OVRD,
2675 .lvl2_mask = BIT(22),
2676 },
2677};
2678
2679int tegra210_clk_handle_mbist_war(unsigned int id)
2680{
2681 int err;
2682 struct tegra210_domain_mbist_war *mbist_war;
2683
2684 if (id >= ARRAY_SIZE(tegra210_pg_mbist_war)) {
2685 WARN(1, "unknown domain id in MBIST WAR handler\n");
2686 return -EINVAL;
2687 }
2688
2689 mbist_war = &tegra210_pg_mbist_war[id];
2690 if (!mbist_war->handle_lvl2_ovr)
2691 return 0;
2692
2693 if (mbist_war->num_clks && !mbist_war->clks)
2694 return -ENODEV;
2695
2696 err = clk_bulk_prepare_enable(mbist_war->num_clks, mbist_war->clks);
2697 if (err < 0)
2698 return err;
2699
2700 mutex_lock(&lvl2_ovr_lock);
2701
2702 mbist_war->handle_lvl2_ovr(mbist_war);
2703
2704 mutex_unlock(&lvl2_ovr_lock);
2705
2706 clk_bulk_disable_unprepare(mbist_war->num_clks, mbist_war->clks);
2707
2708 return 0;
2709}
2710
2421void tegra210_put_utmipll_in_iddq(void) 2711void tegra210_put_utmipll_in_iddq(void)
2422{ 2712{
2423 u32 reg; 2713 u32 reg;
@@ -2654,6 +2944,13 @@ static struct tegra_periph_init_data tegra210_periph[] = {
2654 sor1_parents_idx, 0, &sor1_lock), 2944 sor1_parents_idx, 0, &sor1_lock),
2655}; 2945};
2656 2946
2947static const char * const la_parents[] = {
2948 "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_re_out1", "pll_a1", "clk_m", "pll_c4_out0"
2949};
2950
2951static struct tegra_clk_periph tegra210_la =
2952 TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, 0);
2953
2657static __init void tegra210_periph_clk_init(void __iomem *clk_base, 2954static __init void tegra210_periph_clk_init(void __iomem *clk_base,
2658 void __iomem *pmc_base) 2955 void __iomem *pmc_base)
2659{ 2956{
@@ -2700,6 +2997,12 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
2700 periph_clk_enb_refcnt); 2997 periph_clk_enb_refcnt);
2701 clks[TEGRA210_CLK_DSIB] = clk; 2998 clks[TEGRA210_CLK_DSIB] = clk;
2702 2999
3000 /* la */
3001 clk = tegra_clk_register_periph("la", la_parents,
3002 ARRAY_SIZE(la_parents), &tegra210_la, clk_base,
3003 CLK_SOURCE_LA, 0);
3004 clks[TEGRA210_CLK_LA] = clk;
3005
2703 /* emc mux */ 3006 /* emc mux */
2704 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, 3007 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
2705 ARRAY_SIZE(mux_pllmcp_clkm), 0, 3008 ARRAY_SIZE(mux_pllmcp_clkm), 0,
@@ -3025,7 +3328,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
3025 { TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, 3328 { TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
3026 { TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1 }, 3329 { TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1 },
3027 { TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1 }, 3330 { TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1 },
3028 { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 1 }, 3331 { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 0 },
3029 { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, 3332 { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 },
3030 { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, 3333 { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 },
3031 { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, 3334 { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 },
@@ -3040,7 +3343,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
3040 { TEGRA210_CLK_XUSB_DEV_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 }, 3343 { TEGRA210_CLK_XUSB_DEV_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 },
3041 { TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0 }, 3344 { TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0 },
3042 { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0 }, 3345 { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0 },
3043 { TEGRA210_CLK_EMC, TEGRA210_CLK_CLK_MAX, 0, 1 },
3044 { TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1 }, 3346 { TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1 },
3045 { TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1 }, 3347 { TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1 },
3046 /* TODO find a way to enable this on-demand */ 3348 /* TODO find a way to enable this on-demand */
@@ -3149,6 +3451,37 @@ static int tegra210_reset_deassert(unsigned long id)
3149 return 0; 3451 return 0;
3150} 3452}
3151 3453
3454static void tegra210_mbist_clk_init(void)
3455{
3456 unsigned int i, j;
3457
3458 for (i = 0; i < ARRAY_SIZE(tegra210_pg_mbist_war); i++) {
3459 unsigned int num_clks = tegra210_pg_mbist_war[i].num_clks;
3460 struct clk_bulk_data *clk_data;
3461
3462 if (!num_clks)
3463 continue;
3464
3465 clk_data = kmalloc_array(num_clks, sizeof(*clk_data),
3466 GFP_KERNEL);
3467 if (WARN_ON(!clk_data))
3468 return;
3469
3470 tegra210_pg_mbist_war[i].clks = clk_data;
3471 for (j = 0; j < num_clks; j++) {
3472 int clk_id = tegra210_pg_mbist_war[i].clk_init_data[j];
3473 struct clk *clk = clks[clk_id];
3474
3475 if (WARN(IS_ERR(clk), "clk_id: %d\n", clk_id)) {
3476 kfree(clk_data);
3477 tegra210_pg_mbist_war[i].clks = NULL;
3478 break;
3479 }
3480 clk_data[j].clk = clk;
3481 }
3482 }
3483}
3484
3152/** 3485/**
3153 * tegra210_clock_init - Tegra210-specific clock initialization 3486 * tegra210_clock_init - Tegra210-specific clock initialization
3154 * @np: struct device_node * of the DT node for the SoC CAR IP block 3487 * @np: struct device_node * of the DT node for the SoC CAR IP block
@@ -3183,6 +3516,24 @@ static void __init tegra210_clock_init(struct device_node *np)
3183 return; 3516 return;
3184 } 3517 }
3185 3518
3519 ahub_base = ioremap(TEGRA210_AHUB_BASE, SZ_64K);
3520 if (!ahub_base) {
3521 pr_err("ioremap tegra210 APE failed\n");
3522 return;
3523 }
3524
3525 dispa_base = ioremap(TEGRA210_DISPA_BASE, SZ_256K);
3526 if (!dispa_base) {
3527 pr_err("ioremap tegra210 DISPA failed\n");
3528 return;
3529 }
3530
3531 vic_base = ioremap(TEGRA210_VIC_BASE, SZ_256K);
3532 if (!vic_base) {
3533 pr_err("ioremap tegra210 VIC failed\n");
3534 return;
3535 }
3536
3186 clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX, 3537 clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX,
3187 TEGRA210_CAR_BANK_COUNT); 3538 TEGRA210_CAR_BANK_COUNT);
3188 if (!clks) 3539 if (!clks)
@@ -3219,6 +3570,8 @@ static void __init tegra210_clock_init(struct device_node *np)
3219 tegra_add_of_provider(np); 3570 tegra_add_of_provider(np);
3220 tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); 3571 tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
3221 3572
3573 tegra210_mbist_clk_init();
3574
3222 tegra_cpu_car_ops = &tegra210_cpu_car_ops; 3575 tegra_cpu_car_ops = &tegra210_cpu_car_ops;
3223} 3576}
3224CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); 3577CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);