aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2018-01-25 09:00:12 -0500
committerThierry Reding <treding@nvidia.com>2018-03-08 13:18:08 -0500
commite403d00573431e1e3de1710a91c6090c60ec16af (patch)
tree5f6822fecb0e38b045b2fcf1a2848920cace7542
parentcbfc8d0a85aa72ad66227c69b08904143dc73bbb (diff)
clk: tegra: MBIST work around for Tegra210
Tegra210 has a hw bug which can cause IP blocks to lock up when ungating a domain. The reason is that the logic responsible for resetting the memory built-in self test mode can come up in an undefined state because its clock is gated by a second level clock gate (SLCG). Work around this by making sure the logic will get some clock edges by ensuring the relevant clock is enabled and temporarily override the relevant SLCGs. Unfortunately for some IP blocks, the control bits for overriding the SLCGs are not in CAR, but in the IP block itself. This means we need to map a few extra register banks in the clock code. Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> Reviewed-by: Jon Hunter <jonathanh@nvidia.com> Tested-by: Jon Hunter <jonathanh@nvidia.com> Tested-by: Hector Martin <marcan@marcan.st> Tested-by: Andre Heider <a.heider@gmail.com> Tested-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> fixup mbist
-rw-r--r--drivers/clk/tegra/clk-tegra210.c344
-rw-r--r--include/linux/clk/tegra.h1
2 files changed, 343 insertions, 2 deletions
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index f790c2dc5b5d..946d708add1e 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"
@@ -232,6 +234,30 @@
232#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 234#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
233#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac 235#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
234 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
235/* 261/*
236 * 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
237 * (-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
@@ -256,8 +282,22 @@ static struct cpu_clk_suspend_context {
256} tegra210_cpu_clk_sctx; 282} tegra210_cpu_clk_sctx;
257#endif 283#endif
258 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
259static void __iomem *clk_base; 296static void __iomem *clk_base;
260static void __iomem *pmc_base; 297static void __iomem *pmc_base;
298static void __iomem *ahub_base;
299static void __iomem *dispa_base;
300static void __iomem *vic_base;
261 301
262static unsigned long osc_freq; 302static unsigned long osc_freq;
263static unsigned long pll_ref_freq; 303static unsigned long pll_ref_freq;
@@ -268,6 +308,7 @@ static DEFINE_SPINLOCK(pll_re_lock);
268static DEFINE_SPINLOCK(pll_u_lock); 308static DEFINE_SPINLOCK(pll_u_lock);
269static DEFINE_SPINLOCK(sor1_lock); 309static DEFINE_SPINLOCK(sor1_lock);
270static DEFINE_SPINLOCK(emc_lock); 310static DEFINE_SPINLOCK(emc_lock);
311static DEFINE_MUTEX(lvl2_ovr_lock);
271 312
272/* possible OSC frequencies in Hz */ 313/* possible OSC frequencies in Hz */
273static unsigned long tegra210_input_freq[] = { 314static unsigned long tegra210_input_freq[] = {
@@ -311,6 +352,8 @@ static const char *mux_pllmcp_clkm[] = {
311#define PLLA_MISC2_WRITE_MASK 0x06ffffff 352#define PLLA_MISC2_WRITE_MASK 0x06ffffff
312 353
313/* PLLD */ 354/* PLLD */
355#define PLLD_BASE_CSI_CLKSOURCE (1 << 23)
356
314#define PLLD_MISC0_EN_SDM (1 << 16) 357#define PLLD_MISC0_EN_SDM (1 << 16)
315#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17) 358#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17)
316#define PLLD_MISC0_LOCK_ENABLE (1 << 18) 359#define PLLD_MISC0_LOCK_ENABLE (1 << 18)
@@ -514,6 +557,115 @@ void tegra210_set_sata_pll_seq_sw(bool state)
514} 557}
515EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); 558EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw);
516 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
517static inline void _pll_misc_chk_default(void __iomem *base, 669static inline void _pll_misc_chk_default(void __iomem *base,
518 struct tegra_clk_pll_params *params, 670 struct tegra_clk_pll_params *params,
519 u8 misc_num, u32 default_val, u32 mask) 671 u8 misc_num, u32 default_val, u32 mask)
@@ -2412,13 +2564,150 @@ static struct tegra_audio_clk_info tegra210_audio_plls[] = {
2412 { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" }, 2564 { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" },
2413}; 2565};
2414 2566
2415static struct clk **clks;
2416
2417static const char * const aclk_parents[] = { 2567static const char * const aclk_parents[] = {
2418 "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",
2419 "clk_m" 2569 "clk_m"
2420}; 2570};
2421 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
2422void tegra210_put_utmipll_in_iddq(void) 2711void tegra210_put_utmipll_in_iddq(void)
2423{ 2712{
2424 u32 reg; 2713 u32 reg;
@@ -3163,6 +3452,37 @@ static int tegra210_reset_deassert(unsigned long id)
3163 return 0; 3452 return 0;
3164} 3453}
3165 3454
3455static void tegra210_mbist_clk_init(void)
3456{
3457 unsigned int i, j;
3458
3459 for (i = 0; i < ARRAY_SIZE(tegra210_pg_mbist_war); i++) {
3460 unsigned int num_clks = tegra210_pg_mbist_war[i].num_clks;
3461 struct clk_bulk_data *clk_data;
3462
3463 if (!num_clks)
3464 continue;
3465
3466 clk_data = kmalloc_array(num_clks, sizeof(*clk_data),
3467 GFP_KERNEL);
3468 if (WARN_ON(!clk_data))
3469 return;
3470
3471 tegra210_pg_mbist_war[i].clks = clk_data;
3472 for (j = 0; j < num_clks; j++) {
3473 int clk_id = tegra210_pg_mbist_war[i].clk_init_data[j];
3474 struct clk *clk = clks[clk_id];
3475
3476 if (WARN(IS_ERR(clk), "clk_id: %d\n", clk_id)) {
3477 kfree(clk_data);
3478 tegra210_pg_mbist_war[i].clks = NULL;
3479 break;
3480 }
3481 clk_data[j].clk = clk;
3482 }
3483 }
3484}
3485
3166/** 3486/**
3167 * tegra210_clock_init - Tegra210-specific clock initialization 3487 * tegra210_clock_init - Tegra210-specific clock initialization
3168 * @np: struct device_node * of the DT node for the SoC CAR IP block 3488 * @np: struct device_node * of the DT node for the SoC CAR IP block
@@ -3197,6 +3517,24 @@ static void __init tegra210_clock_init(struct device_node *np)
3197 return; 3517 return;
3198 } 3518 }
3199 3519
3520 ahub_base = ioremap(TEGRA210_AHUB_BASE, SZ_64K);
3521 if (!ahub_base) {
3522 pr_err("ioremap tegra210 APE failed\n");
3523 return;
3524 }
3525
3526 dispa_base = ioremap(TEGRA210_DISPA_BASE, SZ_256K);
3527 if (!dispa_base) {
3528 pr_err("ioremap tegra210 DISPA failed\n");
3529 return;
3530 }
3531
3532 vic_base = ioremap(TEGRA210_VIC_BASE, SZ_256K);
3533 if (!vic_base) {
3534 pr_err("ioremap tegra210 VIC failed\n");
3535 return;
3536 }
3537
3200 clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX, 3538 clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX,
3201 TEGRA210_CAR_BANK_COUNT); 3539 TEGRA210_CAR_BANK_COUNT);
3202 if (!clks) 3540 if (!clks)
@@ -3233,6 +3571,8 @@ static void __init tegra210_clock_init(struct device_node *np)
3233 tegra_add_of_provider(np); 3571 tegra_add_of_provider(np);
3234 tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); 3572 tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
3235 3573
3574 tegra210_mbist_clk_init();
3575
3236 tegra_cpu_car_ops = &tegra210_cpu_car_ops; 3576 tegra_cpu_car_ops = &tegra210_cpu_car_ops;
3237} 3577}
3238CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); 3578CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index d23c9cf26993..afb9edfa5d58 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -128,5 +128,6 @@ extern void tegra210_sata_pll_hw_sequence_start(void);
128extern void tegra210_set_sata_pll_seq_sw(bool state); 128extern void tegra210_set_sata_pll_seq_sw(bool state);
129extern void tegra210_put_utmipll_in_iddq(void); 129extern void tegra210_put_utmipll_in_iddq(void);
130extern void tegra210_put_utmipll_out_iddq(void); 130extern void tegra210_put_utmipll_out_iddq(void);
131extern int tegra210_clk_handle_mbist_war(unsigned int id);
131 132
132#endif /* __LINUX_CLK_TEGRA_H_ */ 133#endif /* __LINUX_CLK_TEGRA_H_ */