Files
linux-nvgpu/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c
Supriya bb51cf9ec6 gpu: nvgpu: Skip reg read of gpc2clk
Bug 200066741

As we are just getting out of reset and this reg is not
written before, so we dont stand the risk of loosing
any data

Change-Id: Ifc1bcaa3c224038e4e2a47882a4523f7633cb660
Signed-off-by: Supriya <ssharatkumar@nvidia.com>
Reviewed-on: http://git-master/r/715652
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
2015-04-04 18:59:25 -07:00

98 lines
2.7 KiB
C

/*
* GK20A priv ring
*
* Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/delay.h> /* for mdelay */
#include "gk20a.h"
#include "hw_mc_gk20a.h"
#include "hw_pri_ringmaster_gk20a.h"
#include "hw_pri_ringstation_sys_gk20a.h"
#include "hw_trim_gk20a.h"
void gk20a_reset_priv_ring(struct gk20a *g)
{
u32 data = 0;
if (tegra_platform_is_linsim())
return;
/* Skipping read and then writeback to this reg, as we are just getting
* out of reset, and before this call, the reg is not written to*/
data = set_field(data,
trim_sys_gpc2clk_out_bypdiv_m(),
trim_sys_gpc2clk_out_bypdiv_f(0));
gk20a_writel(g, trim_sys_gpc2clk_out_r(), data);
gk20a_reset(g, mc_enable_priv_ring_enabled_f());
if (g->ops.clock_gating.slcg_priring_load_gating_prod)
g->ops.clock_gating.slcg_priring_load_gating_prod(g,
g->slcg_enabled);
gk20a_writel(g,pri_ringmaster_command_r(),
0x4);
gk20a_writel(g, pri_ringstation_sys_decode_config_r(),
0x2);
gk20a_readl(g, pri_ringstation_sys_decode_config_r());
}
void gk20a_priv_ring_isr(struct gk20a *g)
{
u32 status0, status1;
u32 cmd;
s32 retry = 100;
if (tegra_platform_is_linsim())
return;
status0 = gk20a_readl(g, pri_ringmaster_intr_status0_r());
status1 = gk20a_readl(g, pri_ringmaster_intr_status1_r());
gk20a_dbg_info("ringmaster intr status0: 0x%08x,"
"status1: 0x%08x", status0, status1);
if (status0 & (0x1 | 0x2 | 0x4)) {
gk20a_reset_priv_ring(g);
}
cmd = gk20a_readl(g, pri_ringmaster_command_r());
cmd = set_field(cmd, pri_ringmaster_command_cmd_m(),
pri_ringmaster_command_cmd_ack_interrupt_f());
gk20a_writel(g, pri_ringmaster_command_r(), cmd);
do {
cmd = pri_ringmaster_command_cmd_v(
gk20a_readl(g, pri_ringmaster_command_r()));
usleep_range(20, 40);
} while (cmd != pri_ringmaster_command_cmd_no_cmd_v() && --retry);
if (retry <= 0)
gk20a_warn(dev_from_gk20a(g),
"priv ringmaster cmd ack too many retries");
status0 = gk20a_readl(g, pri_ringmaster_intr_status0_r());
status1 = gk20a_readl(g, pri_ringmaster_intr_status1_r());
gk20a_dbg_info("ringmaster intr status0: 0x%08x,"
" status1: 0x%08x", status0, status1);
}