From patchwork Thu Nov 16 15:29:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter De Schrijver X-Patchwork-Id: 838624 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yd4tk59p8z9s7f for ; Fri, 17 Nov 2017 02:30:06 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759925AbdKPPaF (ORCPT ); Thu, 16 Nov 2017 10:30:05 -0500 Received: from hqemgate15.nvidia.com ([216.228.121.64]:6500 "EHLO hqemgate15.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753334AbdKPPaD (ORCPT ); Thu, 16 Nov 2017 10:30:03 -0500 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate15.nvidia.com id ; Thu, 16 Nov 2017 07:30:01 -0800 Received: from HQMAIL105.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Thu, 16 Nov 2017 07:30:03 -0800 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Thu, 16 Nov 2017 07:30:03 -0800 Received: from UKMAIL101.nvidia.com (10.26.138.13) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Thu, 16 Nov 2017 15:30:02 +0000 Received: from tbergstrom-lnx.Nvidia.com (10.21.24.170) by UKMAIL101.nvidia.com (10.26.138.13) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Thu, 16 Nov 2017 15:29:58 +0000 Received: from tbergstrom-lnx.Nvidia.com (localhost [127.0.0.1]) by tbergstrom-lnx.Nvidia.com (Postfix) with ESMTP id 224B7F8001A; Thu, 16 Nov 2017 17:29:58 +0200 (EET) From: Peter De Schrijver To: , CC: Peter De Schrijver Subject: [PATCH v2 1/4] clk: tegra: Add la clock for Tegra210 Date: Thu, 16 Nov 2017 17:29:52 +0200 Message-ID: <1510846195-28555-2-git-send-email-pdeschrijver@nvidia.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1510846195-28555-1-git-send-email-pdeschrijver@nvidia.com> References: <1510846195-28555-1-git-send-email-pdeschrijver@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 X-Originating-IP: [10.21.24.170] X-ClientProxiedBy: UKMAIL102.nvidia.com (10.26.138.15) To UKMAIL101.nvidia.com (10.26.138.13) Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org This clock is needed by the memory built-in self test work around. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-tegra210.c | 12 ++++++++++++ include/dt-bindings/clock/tegra210-car.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 6d7a613..55a5b7f 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -40,6 +40,7 @@ #define CLK_SOURCE_CSITE 0x1d4 #define CLK_SOURCE_EMC 0x19c +#define CLK_SOURCE_LA 0x1f8 #define PLLC_BASE 0x80 #define PLLC_OUT 0x84 @@ -2628,6 +2629,13 @@ static int tegra210_init_pllu(void) return 0; } +static const char * const la_parents[] = { + "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_re_out1", "pll_a1", "clk_m", "pll_c4_out0" +}; + +static struct tegra_clk_periph tegra210_la = + TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, 0); + static __init void tegra210_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base) { @@ -2667,6 +2675,10 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base, periph_clk_enb_refcnt); clks[TEGRA210_CLK_DSIB] = clk; + /* la */ + clk = tegra_clk_register_periph("la", la_parents, + ARRAY_SIZE(la_parents), &tegra210_la, clk_base, + CLK_SOURCE_LA, 0); /* emc mux */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, ARRAY_SIZE(mux_pllmcp_clkm), 0, diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h index a9dc145..5df857a 100644 --- a/include/dt-bindings/clock/tegra210-car.h +++ b/include/dt-bindings/clock/tegra210-car.h @@ -95,7 +95,7 @@ #define TEGRA210_CLK_CSITE 73 /* 74 */ /* 75 */ -/* 76 */ +#define TEGRA210_CLK_LA 76 /* 77 */ #define TEGRA210_CLK_SOC_THERM 78 #define TEGRA210_CLK_DTV 79 From patchwork Thu Nov 16 15:29:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter De Schrijver X-Patchwork-Id: 838627 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yd4tn3944z9s83 for ; Fri, 17 Nov 2017 02:30:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759929AbdKPPaI (ORCPT ); Thu, 16 Nov 2017 10:30:08 -0500 Received: from hqemgate14.nvidia.com ([216.228.121.143]:18438 "EHLO hqemgate14.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759924AbdKPPaF (ORCPT ); Thu, 16 Nov 2017 10:30:05 -0500 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate14.nvidia.com id ; Thu, 16 Nov 2017 07:29:58 -0800 Received: from HQMAIL105.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Thu, 16 Nov 2017 07:30:04 -0800 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Thu, 16 Nov 2017 07:30:04 -0800 Received: from UKMAIL101.nvidia.com (10.26.138.13) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Thu, 16 Nov 2017 15:30:04 +0000 Received: from tbergstrom-lnx.Nvidia.com (10.21.24.170) by UKMAIL101.nvidia.com (10.26.138.13) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Thu, 16 Nov 2017 15:29:59 +0000 Received: from tbergstrom-lnx.Nvidia.com (localhost [127.0.0.1]) by tbergstrom-lnx.Nvidia.com (Postfix) with ESMTP id 2EF86F8001F; Thu, 16 Nov 2017 17:29:58 +0200 (EET) From: Peter De Schrijver To: , CC: Peter De Schrijver Subject: [PATCH v2 2/4] clk: tegra: add fence_delay for clock registers Date: Thu, 16 Nov 2017 17:29:53 +0200 Message-ID: <1510846195-28555-3-git-send-email-pdeschrijver@nvidia.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1510846195-28555-1-git-send-email-pdeschrijver@nvidia.com> References: <1510846195-28555-1-git-send-email-pdeschrijver@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 X-Originating-IP: [10.21.24.170] X-ClientProxiedBy: UKMAIL101.nvidia.com (10.26.138.13) To UKMAIL101.nvidia.com (10.26.138.13) Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org To ensure writes to clock registers have properly propagated through the clock control logic and state machines, we need to ensure the writes have been posted in the registers and wait for 1us after that. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 872f118..d5badbe 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -809,4 +809,11 @@ static inline struct clk *tegra_clk_register_emc(void __iomem *base, u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); +/* Combined read fence with delay */ +#define fence_udelay(delay, reg) \ + do { \ + readl(reg); \ + udelay(delay); \ + } while(0) + #endif /* TEGRA_CLK_H */ From patchwork Thu Nov 16 15:29:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter De Schrijver X-Patchwork-Id: 838626 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yd4tm4Jsjz9s7M for ; Fri, 17 Nov 2017 02:30:08 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750905AbdKPPaH (ORCPT ); Thu, 16 Nov 2017 10:30:07 -0500 Received: from hqemgate15.nvidia.com ([216.228.121.64]:6502 "EHLO hqemgate15.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750917AbdKPPaE (ORCPT ); Thu, 16 Nov 2017 10:30:04 -0500 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqemgate15.nvidia.com id ; Thu, 16 Nov 2017 07:30:02 -0800 Received: from HQMAIL105.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Thu, 16 Nov 2017 07:30:41 -0800 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Thu, 16 Nov 2017 07:30:41 -0800 Received: from UKMAIL101.nvidia.com (10.26.138.13) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Thu, 16 Nov 2017 15:30:03 +0000 Received: from tbergstrom-lnx.Nvidia.com (10.21.24.170) by UKMAIL101.nvidia.com (10.26.138.13) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Thu, 16 Nov 2017 15:29:58 +0000 Received: from tbergstrom-lnx.Nvidia.com (localhost [127.0.0.1]) by tbergstrom-lnx.Nvidia.com (Postfix) with ESMTP id 3BB42F8004B; Thu, 16 Nov 2017 17:29:58 +0200 (EET) From: Peter De Schrijver To: , CC: Peter De Schrijver Subject: [PATCH v2 3/4] clk: tegra: MBIST work around for Tegra210 Date: Thu, 16 Nov 2017 17:29:54 +0200 Message-ID: <1510846195-28555-4-git-send-email-pdeschrijver@nvidia.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1510846195-28555-1-git-send-email-pdeschrijver@nvidia.com> References: <1510846195-28555-1-git-send-email-pdeschrijver@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 X-Originating-IP: [10.21.24.170] X-ClientProxiedBy: UKMAIL101.nvidia.com (10.26.138.13) To UKMAIL101.nvidia.com (10.26.138.13) Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org 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 it doesn't get a clock or reset signal. 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 second level clock gates (SLCG). 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 --- drivers/clk/tegra/clk-tegra210.c | 359 ++++++++++++++++++++++++++++++++++++++- include/linux/clk/tegra.h | 1 + 2 files changed, 358 insertions(+), 2 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 55a5b7f..72de0e9 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -22,10 +22,12 @@ #include #include #include +#include #include #include #include #include +#include #include "clk.h" #include "clk-id.h" @@ -231,6 +233,30 @@ #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac +#define LVL2_CLK_GATE_OVRA 0xf8 +#define LVL2_CLK_GATE_OVRC 0x3a0 +#define LVL2_CLK_GATE_OVRD 0x3a4 +#define LVL2_CLK_GATE_OVRE 0x554 + +/* I2S registers to handle during APE MBIST WAR */ +#define TEGRA210_I2S_BASE 0x11000 +#define TEGRA210_I2S_SIZE 0x100 +#define TEGRA210_I2S_CTRLS 5 +#define TEGRA210_I2S_CG 0x88 +#define TEGRA210_I2S_CTRL 0xa0 + +/* DISPA registers to handle during MBIST WAR */ +#define DC_CMD_DISPLAY_COMMAND 0xc8 +#define DC_COM_DSC_TOP_CTL 0xcf8 + +/* VIC register to handle during MBIST WAR */ +#define NV_PVIC_THI_SLCG_OVERRIDE_LOW 0x8c + +/* APE, DISPA and VIC base addesses needed for MBIST WAR */ +#define TEGRA210_APE_BASE 0x702c0000 +#define TEGRA210_DISPA_BASE 0x54200000 +#define TEGRA210_VIC_BASE 0x54340000 + /* * SDM fractional divisor is 16-bit 2's complement signed number within * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned @@ -255,8 +281,22 @@ } tegra210_cpu_clk_sctx; #endif +struct tegra210_domain_mbist_war { + int (*handle_lvl2_ovr)(struct tegra210_domain_mbist_war *mbist); + const u32 lvl2_offset; + const u32 lvl2_mask; + const unsigned int num_clks; + const unsigned int *clk_init_data; + struct clk_bulk_data *clks; +}; + +static struct clk **clks; + static void __iomem *clk_base; static void __iomem *pmc_base; +static void __iomem *ape_base; +static void __iomem *dispa_base; +static void __iomem *vic_base; static unsigned long osc_freq; static unsigned long pll_ref_freq; @@ -266,6 +306,7 @@ static DEFINE_SPINLOCK(pll_re_lock); static DEFINE_SPINLOCK(pll_u_lock); static DEFINE_SPINLOCK(emc_lock); +static DEFINE_MUTEX(lvl2_ovr_lock); /* possible OSC frequencies in Hz */ static unsigned long tegra210_input_freq[] = { @@ -309,6 +350,8 @@ #define PLLA_MISC2_WRITE_MASK 0x06ffffff /* PLLD */ +#define PLLD_BASE_CSI_CLKSOURCE (1 << 23) + #define PLLD_MISC0_EN_SDM (1 << 16) #define PLLD_MISC0_LOCK_OVERRIDE (1 << 17) #define PLLD_MISC0_LOCK_ENABLE (1 << 18) @@ -512,6 +555,176 @@ void tegra210_set_sata_pll_seq_sw(bool state) } EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); +static int tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist) +{ + u32 val; + int err; + + err = clk_bulk_prepare_enable(mbist->num_clks, mbist->clks); + if (err < 0) + return err; + + mutex_lock(&lvl2_ovr_lock); + + val = readl_relaxed(clk_base + mbist->lvl2_offset); + writel_relaxed(val | mbist->lvl2_mask, clk_base + mbist->lvl2_offset); + fence_udelay(1, clk_base); + writel_relaxed(val, clk_base + mbist->lvl2_offset); + fence_udelay(1, clk_base); + + mutex_unlock(&lvl2_ovr_lock); + + clk_bulk_disable_unprepare(mbist->num_clks, mbist->clks); + + return 0; +} + +static int tegra210_venc_mbist_war(struct tegra210_domain_mbist_war *mbist) +{ + u32 csi_src, ovra, ovre; + int err; + unsigned long flags = 0; + + err = clk_bulk_prepare_enable(mbist->num_clks, mbist->clks); + if (err < 0) + return err; + + mutex_lock(&lvl2_ovr_lock); + spin_lock_irqsave(&pll_d_lock, flags); + + csi_src = readl_relaxed(clk_base + PLLD_BASE); + writel_relaxed(csi_src | PLLD_BASE_CSI_CLKSOURCE, clk_base + PLLD_BASE); + fence_udelay(1, clk_base); + + ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA); + writel_relaxed(ovra | BIT(15), clk_base + LVL2_CLK_GATE_OVRA); + ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE); + writel_relaxed(ovre | BIT(3), clk_base + LVL2_CLK_GATE_OVRE); + fence_udelay(1, clk_base); + + writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA); + writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE); + writel_relaxed(csi_src, clk_base + PLLD_BASE); + fence_udelay(1, clk_base); + + spin_unlock_irqrestore(&pll_d_lock, flags); + mutex_unlock(&lvl2_ovr_lock); + + clk_bulk_disable_unprepare(mbist->num_clks, mbist->clks); + + return 0; +} + +static int tegra210_disp_mbist_war(struct tegra210_domain_mbist_war *mbist) +{ + u32 ovra, dsc_top_ctrl; + int err; + + err = clk_bulk_prepare_enable(mbist->num_clks, mbist->clks); + if (err < 0) + return err; + + mutex_lock(&lvl2_ovr_lock); + + ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA); + writel_relaxed(ovra | BIT(1), clk_base + LVL2_CLK_GATE_OVRA); + fence_udelay(1, clk_base); + + dsc_top_ctrl = readl_relaxed(dispa_base + DC_COM_DSC_TOP_CTL); + writel_relaxed(dsc_top_ctrl | BIT(2), dispa_base + DC_COM_DSC_TOP_CTL); + readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND); + writel_relaxed(dsc_top_ctrl, dispa_base + DC_COM_DSC_TOP_CTL); + readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND); + + writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA); + fence_udelay(1, clk_base); + + mutex_unlock(&lvl2_ovr_lock); + + clk_bulk_disable_unprepare(mbist->num_clks, mbist->clks); + + return 0; +} + +static int tegra210_vic_mbist_war(struct tegra210_domain_mbist_war *mbist) +{ + u32 ovre, val; + int err; + + err = clk_prepare_enable(clks[TEGRA210_CLK_HOST1X]); + if (err < 0) + return err; + + mutex_lock(&lvl2_ovr_lock); + + ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE); + writel_relaxed(ovre | BIT(5), clk_base + LVL2_CLK_GATE_OVRE); + fence_udelay(1, clk_base); + + val = readl_relaxed(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW); + writel_relaxed(val | BIT(0) | GENMASK(7,2) | BIT(24), + vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW); + readl(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW); + udelay(1); + writel_relaxed(val, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW); + readl(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW); + + writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE); + fence_udelay(1, clk_base); + + mutex_unlock(&lvl2_ovr_lock); + + clk_disable_unprepare(clks[TEGRA210_CLK_HOST1X]); + + return 0; +} + +static int tegra210_ape_mbist_war(struct tegra210_domain_mbist_war *mbist) +{ + int err, i; + u32 ovrc, ovre; + void __iomem *i2s_base; + + err = clk_bulk_prepare_enable(mbist->num_clks, mbist->clks); + if (err < 0) + return err; + + mutex_lock(&lvl2_ovr_lock); + + ovrc = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRC); + ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE); + writel_relaxed(ovrc | BIT(1), clk_base + LVL2_CLK_GATE_OVRC); + writel_relaxed(ovre | BIT(10) | BIT(11), + clk_base + LVL2_CLK_GATE_OVRE); + fence_udelay(1, clk_base); + + i2s_base = ape_base + TEGRA210_I2S_BASE; + for (i = 0; i < TEGRA210_I2S_CTRLS; i++) { + u32 i2s_ctrl; + + i2s_ctrl = readl_relaxed(i2s_base + TEGRA210_I2S_CTRL); + writel_relaxed(i2s_ctrl | BIT(10), + i2s_base + TEGRA210_I2S_CTRL); + writel_relaxed(0, i2s_base + TEGRA210_I2S_CG); + readl(i2s_base + TEGRA210_I2S_CG); + writel_relaxed(1, i2s_base + TEGRA210_I2S_CG); + writel_relaxed(i2s_ctrl, i2s_base + TEGRA210_I2S_CTRL); + readl(i2s_base + TEGRA210_I2S_CTRL); + + i2s_base += TEGRA210_I2S_SIZE; + } + + writel_relaxed(ovrc, clk_base + LVL2_CLK_GATE_OVRC); + writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE); + fence_udelay(1, clk_base); + + mutex_unlock(&lvl2_ovr_lock); + + clk_bulk_disable_unprepare(mbist->num_clks, mbist->clks); + + return 0; +} + static inline void _pll_misc_chk_default(void __iomem *base, struct tegra_clk_pll_params *params, u8 misc_num, u32 default_val, u32 mask) @@ -2410,13 +2623,137 @@ struct utmi_clk_param { { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" }, }; -static struct clk **clks; - static const char * const aclk_parents[] = { "pll_a1", "pll_c", "pll_p", "pll_a_out0", "pll_c2", "pll_c3", "clk_m" }; +static const unsigned int nvjpg_slcg_clkids[] = { TEGRA210_CLK_NVDEC }; +static const unsigned int nvdec_slcg_clkids[] = { TEGRA210_CLK_NVJPG }; +static const unsigned int sor_slcg_clkids[] = { TEGRA210_CLK_HDA2CODEC_2X, + TEGRA210_CLK_HDA2HDMI, TEGRA210_CLK_DISP1, TEGRA210_CLK_DISP2 }; +static const unsigned int disp_slcg_clkids[] = { TEGRA210_CLK_LA, + TEGRA210_CLK_HOST1X}; +static const unsigned int xusba_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST, + TEGRA210_CLK_XUSB_DEV }; +static const unsigned int xusbb_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST, + TEGRA210_CLK_XUSB_SS }; +static const unsigned int xusbc_slcg_clkids[] = { TEGRA210_CLK_XUSB_DEV, + TEGRA210_CLK_XUSB_SS }; +static const unsigned int venc_slcg_clkids[] = { TEGRA210_CLK_HOST1X, + TEGRA210_CLK_PLL_D }; +static const unsigned int ape_slcg_clkids[] = { TEGRA210_CLK_ACLK, + TEGRA210_CLK_I2S0, TEGRA210_CLK_I2S1, TEGRA210_CLK_I2S2, + TEGRA210_CLK_I2S3, TEGRA210_CLK_I2S4, TEGRA210_CLK_SPDIF_OUT, + TEGRA210_CLK_D_AUDIO }; + +static struct tegra210_domain_mbist_war tegra210_pg_mbist_war[] = { + [TEGRA_POWERGATE_VENC] = { + .handle_lvl2_ovr = tegra210_venc_mbist_war, + .num_clks = ARRAY_SIZE(venc_slcg_clkids), + .clk_init_data = venc_slcg_clkids, + }, + [TEGRA_POWERGATE_SATA] = { + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRC, + .lvl2_mask = BIT(0) | BIT(17) | BIT(19), + }, + [TEGRA_POWERGATE_MPE] = { + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRE, + .lvl2_mask = BIT(2), + }, + [TEGRA_POWERGATE_SOR] = { + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .num_clks = ARRAY_SIZE(sor_slcg_clkids), + .clk_init_data = sor_slcg_clkids, + .lvl2_offset = LVL2_CLK_GATE_OVRA, + .lvl2_mask = BIT(1) | BIT(2), + }, + [TEGRA_POWERGATE_DIS] = { + .handle_lvl2_ovr = tegra210_disp_mbist_war, + .num_clks = ARRAY_SIZE(disp_slcg_clkids), + .clk_init_data = disp_slcg_clkids, + }, + [TEGRA_POWERGATE_DISB] = { + .num_clks = ARRAY_SIZE(disp_slcg_clkids), + .clk_init_data = disp_slcg_clkids, + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRA, + .lvl2_mask = BIT(2), + }, + [TEGRA_POWERGATE_XUSBA] = { + .num_clks = ARRAY_SIZE(xusba_slcg_clkids), + .clk_init_data = xusba_slcg_clkids, + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRC, + .lvl2_mask = BIT(30) | BIT(31), + }, + [TEGRA_POWERGATE_XUSBB] = { + .num_clks = ARRAY_SIZE(xusbb_slcg_clkids), + .clk_init_data = xusbb_slcg_clkids, + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRC, + .lvl2_mask = BIT(30) | BIT(31), + }, + [TEGRA_POWERGATE_XUSBC] = { + .num_clks = ARRAY_SIZE(xusbc_slcg_clkids), + .clk_init_data = xusbc_slcg_clkids, + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRC, + .lvl2_mask = BIT(30) | BIT(31), + }, + [TEGRA_POWERGATE_VIC] = { + .handle_lvl2_ovr = tegra210_vic_mbist_war, + }, + [TEGRA_POWERGATE_NVDEC] = { + .num_clks = ARRAY_SIZE(nvdec_slcg_clkids), + .clk_init_data = nvdec_slcg_clkids, + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRC, + .lvl2_mask = BIT(9) | BIT(31), + }, + [TEGRA_POWERGATE_NVJPG] = { + .num_clks = ARRAY_SIZE(nvjpg_slcg_clkids), + .clk_init_data = nvjpg_slcg_clkids, + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRC, + .lvl2_mask = BIT(9) | BIT(31), + }, + [TEGRA_POWERGATE_AUD] = { + .num_clks = ARRAY_SIZE(ape_slcg_clkids), + .clk_init_data = ape_slcg_clkids, + .handle_lvl2_ovr = tegra210_ape_mbist_war, + }, + [TEGRA_POWERGATE_VE2] = { + .handle_lvl2_ovr = tegra210_generic_mbist_war, + .lvl2_offset = LVL2_CLK_GATE_OVRD, + .lvl2_mask = BIT(22), + }, +}; + +void tegra210_handle_mbist_war(unsigned int id) +{ + int err; + + if (id >= ARRAY_SIZE(tegra210_pg_mbist_war)) { + pr_err("unknown domain id in MBIST WAR handler\n"); + WARN_ON(1); + return; + } + + if (!tegra210_pg_mbist_war[id].handle_lvl2_ovr) + return; + + err = + tegra210_pg_mbist_war[id].handle_lvl2_ovr(&tegra210_pg_mbist_war[id]); + if (err < 0) { + pr_err("error handling MBIST WAR for domain: %d\n", id); + WARN_ON(1); + } +} + + void tegra210_put_utmipll_in_iddq(void) { u32 reg; @@ -3148,6 +3485,24 @@ static void __init tegra210_clock_init(struct device_node *np) return; } + ape_base = ioremap(TEGRA210_APE_BASE, 256*1024); + if (!ape_base) { + pr_err("ioremap tegra210 APE failed\n"); + return; + } + + dispa_base = ioremap(TEGRA210_DISPA_BASE, 256*1024); + if (!dispa_base) { + pr_err("ioremap tegra210 DISPA failed\n"); + return; + } + + vic_base = ioremap(TEGRA210_VIC_BASE, 256*1024); + if (!vic_base) { + pr_err("ioremap tegra210 VIC failed\n"); + return; + } + clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX, TEGRA210_CAR_BANK_COUNT); if (!clks) diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index d23c9cf..6d1898b 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -128,5 +128,6 @@ static inline void tegra_cpu_clock_resume(void) extern void tegra210_set_sata_pll_seq_sw(bool state); extern void tegra210_put_utmipll_in_iddq(void); extern void tegra210_put_utmipll_out_iddq(void); +extern void tegra210_handle_mbist_war(unsigned int id); #endif /* __LINUX_CLK_TEGRA_H_ */ From patchwork Thu Nov 16 15:29:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter De Schrijver X-Patchwork-Id: 838625 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yd4tl2R8jz9s7M for ; Fri, 17 Nov 2017 02:30:07 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753334AbdKPPaG (ORCPT ); Thu, 16 Nov 2017 10:30:06 -0500 Received: from hqemgate15.nvidia.com ([216.228.121.64]:6501 "EHLO hqemgate15.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750905AbdKPPaE (ORCPT ); Thu, 16 Nov 2017 10:30:04 -0500 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate15.nvidia.com id ; Thu, 16 Nov 2017 07:30:02 -0800 Received: from HQMAIL105.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Thu, 16 Nov 2017 07:30:03 -0800 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Thu, 16 Nov 2017 07:30:03 -0800 Received: from UKMAIL101.nvidia.com (10.26.138.13) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Thu, 16 Nov 2017 15:30:03 +0000 Received: from tbergstrom-lnx.Nvidia.com (10.21.24.170) by UKMAIL101.nvidia.com (10.26.138.13) with Microsoft SMTP Server (TLS) id 15.0.1293.2; Thu, 16 Nov 2017 15:29:58 +0000 Received: from tbergstrom-lnx.Nvidia.com (localhost [127.0.0.1]) by tbergstrom-lnx.Nvidia.com (Postfix) with ESMTP id 489AFF8004C; Thu, 16 Nov 2017 17:29:58 +0200 (EET) From: Peter De Schrijver To: , CC: Peter De Schrijver Subject: [PATCH v2 4/4] soc/tegra: pmc: apply MBIST work around fo Tegra210 Date: Thu, 16 Nov 2017 17:29:55 +0200 Message-ID: <1510846195-28555-5-git-send-email-pdeschrijver@nvidia.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1510846195-28555-1-git-send-email-pdeschrijver@nvidia.com> References: <1510846195-28555-1-git-send-email-pdeschrijver@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 X-Originating-IP: [10.21.24.170] X-ClientProxiedBy: UKMAIL101.nvidia.com (10.26.138.13) To UKMAIL101.nvidia.com (10.26.138.13) Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Apply the memory built-in self test work around when ungating certain Tegra210 power domains. Signed-off-by: Peter De Schrijver --- drivers/soc/tegra/pmc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 0453ff6..4c0582d 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -142,6 +142,7 @@ struct tegra_pmc_soc { bool has_tsense_reset; bool has_gpu_clamps; + bool needs_mbist_war; const struct tegra_io_pad_soc *io_pads; unsigned int num_io_pads; @@ -411,6 +412,9 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg, usleep_range(10, 20); + if (pg->pmc->soc->needs_mbist_war) + tegra210_handle_mbist_war(pg->id); + if (disable_clocks) tegra_powergate_disable_clocks(pg); @@ -1712,6 +1716,7 @@ static int tegra_pmc_resume(struct device *dev) .cpu_powergates = tegra210_cpu_powergates, .has_tsense_reset = true, .has_gpu_clamps = true, + .needs_mbist_war = true, .num_io_pads = ARRAY_SIZE(tegra210_io_pads), .io_pads = tegra210_io_pads, };