diff options
author | Christopher Freeman <cfreeman@nvidia.com> | 2015-08-14 15:11:26 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-08-28 06:43:42 +0000 |
commit | 4cd0d2f5693093f442a51b4ebb97d30ce4403abd (patch) | |
tree | 9c25973afcdf650a544f8bbc87c72f1a8e1db5e7 /src/soc/nvidia/tegra210 | |
parent | 8c3ab6a5f1e36ddf2c22abacee47afaddd7d0bb8 (diff) | |
download | coreboot-4cd0d2f5693093f442a51b4ebb97d30ce4403abd.tar.xz |
t210: lp0_resume: apply mbist WAR for audio on resume
When power is cut/restored to audio block, mbist workaround must be reapplied
or I2S will not function. Handle this in lp0 resume firmware with the rest of
the mbist WAR. This sequence for audio is also present in boot block code for
T210.
BUG=chrome-os-partner:41249
BRANCH=None
TEST=lp0 suspend/resume with audio playback
Signed-off-by: Patrick Georgi <patrick@georgi-clan.de>
Original-Commit-Id: 84933da8188f8263c19f38ba37e88e32ca46cb3d
Original-Change-Id: Ia6432e8556ee64f528d94f2dc3279b152294e132
Original-Signed-off-by: Christopher Freeman <cfreeman@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/293618
Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Original-Commit-Queue: Anatol Pomazau <anatol@google.com>
Original-Reviewed-by: Tom Warren <twarren@nvidia.com>
Original-Reviewed-by: Anatol Pomazau <anatol@google.com>
Original-Tested-by: Anatol Pomazau <anatol@google.com>
Original-(cherry picked from commit 1e529c3e2ff929975fd654ef75396bc98d3b785c)
Original-Reviewed-on: https://chromium-review.googlesource.com/293886
Original-Commit-Queue: Furquan Shaikh <furquan@chromium.org>
Original-Trybot-Ready: Furquan Shaikh <furquan@chromium.org>
Original-Tested-by: Furquan Shaikh <furquan@chromium.org>
Change-Id: I3e72bc10f7e2bea2fa5f946e25803a7928ce9276
Reviewed-on: http://review.coreboot.org/11394
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/nvidia/tegra210')
-rw-r--r-- | src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c b/src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c index 5ef03d0126..956e8c5856 100644 --- a/src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c +++ b/src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c @@ -31,7 +31,8 @@ enum { MC_CTLR_BASE = 0x70019000, FUSE_BASE = 0x7000F800, EMC_BASE = 0x7001B000, - I2C5_BASE = 0x7000D000 + I2C5_BASE = 0x7000D000, + I2S_BASE = 0x702d1000 }; /* UP tag registers. */ @@ -704,15 +705,77 @@ static void set_pmacro_training_wrptr(void) write32(pmacro_cfg_pm_global, ENABLE_CFG_BYTES); } +static uint32_t *i2s_0_master = (void *)(I2S_BASE + 0x0a0); +static uint32_t *i2s_1_master = (void *)(I2S_BASE + 0x1a0); +static uint32_t *i2s_2_master = (void *)(I2S_BASE + 0x2a0); +static uint32_t *i2s_3_master = (void *)(I2S_BASE + 0x3a0); +static uint32_t *i2s_4_master = (void *)(I2S_BASE + 0x4a0); + +static uint32_t *i2s_0_slcg = (void *)(I2S_BASE + 0x088); +static uint32_t *i2s_1_slcg = (void *)(I2S_BASE + 0x188); +static uint32_t *i2s_2_slcg = (void *)(I2S_BASE + 0x288); +static uint32_t *i2s_3_slcg = (void *)(I2S_BASE + 0x388); +static uint32_t *i2s_4_slcg = (void *)(I2S_BASE + 0x488); + +static uint32_t *clk_rst_ape_clear = (void *)(CLK_RST_BASE + 0x2ac); +static uint32_t *clk_rst_ape_set = (void *)(CLK_RST_BASE + 0x2a8); + static void mbist_workaround(void) { uint32_t clks_to_be_cleared; + uint32_t i2s_read; + + write32(clk_rst_ape_clear, 0x40); + udelay(2); + + i2s_read = read32(i2s_0_master); + i2s_read |= 0x400; + write32(i2s_0_master, i2s_read); + + i2s_read = read32(i2s_0_slcg); + i2s_read &= ~1; + write32(i2s_0_slcg, i2s_read); + + i2s_read = read32(i2s_1_master); + i2s_read |= 0x400; + write32(i2s_1_master, i2s_read); + + i2s_read = read32(i2s_1_slcg); + i2s_read &= ~1; + write32(i2s_1_slcg, i2s_read); + + i2s_read = read32(i2s_2_master); + i2s_read |= 0x400; + write32(i2s_2_master, i2s_read); + + i2s_read = read32(i2s_2_slcg); + i2s_read &= ~1; + write32(i2s_2_slcg, i2s_read); + + i2s_read = read32(i2s_3_master); + i2s_read |= 0x400; + write32(i2s_3_master, i2s_read); + + i2s_read = read32(i2s_3_slcg); + i2s_read &= ~1; + write32(i2s_3_slcg, i2s_read); + + i2s_read = read32(i2s_4_master); + i2s_read |= 0x400; + write32(i2s_4_master, i2s_read); + + i2s_read = read32(i2s_4_slcg); + i2s_read &= ~1; + write32(i2s_4_slcg, i2s_read); + + udelay(2); write32(clk_rst_lvl2_clk_gate_ovra_ptr, 0); write32(clk_rst_lvl2_clk_gate_ovrb_ptr, 0); - write32(clk_rst_lvl2_clk_gate_ovrc_ptr, 0); + write32(clk_rst_lvl2_clk_gate_ovrc_ptr, 0x00000002); write32(clk_rst_lvl2_clk_gate_ovrd_ptr, 0x01000000); /* QSPI OVR=1 */ - write32(clk_rst_lvl2_clk_gate_ovre_ptr, 0); + write32(clk_rst_lvl2_clk_gate_ovre_ptr, 0x00000c00); + clks_to_be_cleared = read32(clk_rst_clk_out_enb_l_ptr); clks_to_be_cleared &= ~MBIST_CLK_ENB_L_0; |