Files
linux-nv-oot/drivers/misc/mods/mods_tegradc.c
Chris Dragan b5b2def304 misc: mods: improve logging and fix SRIOV
* Add new cl_* macros for printing client-specific messages.
  This adds client index to messages in code which is called from
  user space.  This makes it easier to diagnose errors when multiple
  clients (processes) open the driver.
* Use kernel print levels appropriate to messages being printed.
* Print process pid when opening the driver.
* Print information about access token being set or released.
* Print information about PCI devices being enabled or disabled.
  PCI device enablement is tied to the driver getting ownership
  of the device.  It also prevents multiple MODS instances from
  owning the same PCI device.
* Print info about device DMA mask, print device DMA mask when DMA
  mapping fails.
* Print more info about SRIOV actions.
* Disable SRIOV when the driver is being closed by the process
  which enables SRIOV.  Leaving SRIOV enabled when disabling PCI
  device is an error and leads to stale functions, unusable on
  subsequent MODS runs.
* Clean up log messages in a few places.

Change-Id: I51953e984a55c0990e90f89d8260f215c8c58498
Signed-off-by: Chris Dragan <kdragan@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2279439
Tested-by: Ellis Roberts <ellisr@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
2023-04-03 13:27:52 +00:00

152 lines
4.2 KiB
C

/*
* mods_tegradc.c - This file is part of NVIDIA MODS kernel driver.
*
* Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
*
* NVIDIA MODS kernel driver is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* NVIDIA MODS kernel driver is distributed in the hope that 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 NVIDIA MODS kernel driver.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/uaccess.h>
#include <../drivers/video/tegra/dc/dc_priv.h>
#include <video/tegra_dc_ext_kernel.h>
#include <linux/platform/tegra/mc.h>
#include "mods_internal.h"
static void mods_tegra_dc_set_windowattr_basic(
struct mods_client *client,
struct tegra_dc_win *win,
const struct MODS_TEGRA_DC_WINDOW *mods_win)
{
win->global_alpha = 0;
win->z = 0;
win->stride = 0;
win->stride_uv = 0;
win->flags = TEGRA_WIN_FLAG_ENABLED;
if (mods_win->flags & MODS_TEGRA_DC_WINDOW_FLAG_TILED)
win->flags |= TEGRA_WIN_FLAG_TILED;
if (mods_win->flags & MODS_TEGRA_DC_WINDOW_FLAG_SCAN_COL)
win->flags |= TEGRA_WIN_FLAG_SCAN_COLUMN;
win->fmt = mods_win->pixformat;
win->x.full = mods_win->x;
win->y.full = mods_win->y;
win->w.full = mods_win->w;
win->h.full = mods_win->h;
/* XXX verify that this doesn't go outside display's active region */
win->out_x = mods_win->out_x;
win->out_y = mods_win->out_y;
win->out_w = mods_win->out_w;
win->out_h = mods_win->out_h;
cl_debug(DEBUG_TEGRADC,
"set_windowattr_basic window %u:\n"
"\tflags : 0x%08x\n"
"\tfmt : %u\n"
"\tinput : (%u, %u, %u, %u)\n"
"\toutput: (%u, %u, %u, %u)\n",
win->idx, win->flags, win->fmt, dfixed_trunc(win->x),
dfixed_trunc(win->y), dfixed_trunc(win->w),
dfixed_trunc(win->h), win->out_x, win->out_y, win->out_w,
win->out_h);
}
int esc_mods_tegra_dc_config_possible(struct mods_client *client,
struct MODS_TEGRA_DC_CONFIG_POSSIBLE *args)
{
int i;
struct tegra_dc *dc = tegra_dc_get_dc(args->head);
struct tegra_dc_win *dc_wins[DC_N_WINDOWS];
#ifndef CONFIG_TEGRA_ISOMGR
struct clk *emc_clk = 0;
unsigned long max_bandwidth = 0;
unsigned long current_emc_freq = 0;
unsigned long max_available_bandwidth = 0;
#else
int ret = -EINVAL;
#endif
LOG_ENT();
BUG_ON(args->win_num > tegra_dc_get_numof_dispwindows());
if (!dc) {
LOG_EXT();
return -EINVAL;
}
for (i = 0; i < args->win_num; i++) {
int idx = args->windows[i].index;
if (args->windows[i].flags &
MODS_TEGRA_DC_WINDOW_FLAG_ENABLED) {
mods_tegra_dc_set_windowattr_basic(client,
&dc->tmp_wins[idx],
&args->windows[i]);
} else {
dc->tmp_wins[idx].flags = 0;
}
dc_wins[i] = &dc->tmp_wins[idx];
cl_debug(DEBUG_TEGRADC,
"head %u, using index %d for win %d\n",
args->head, i, idx);
}
cl_debug(DEBUG_TEGRADC,
"head %u, dc->mode.pclk %u\n",
args->head, dc->mode.pclk);
#ifndef CONFIG_TEGRA_ISOMGR
max_bandwidth = tegra_dc_get_bandwidth(dc_wins, args->win_num);
emc_clk = clk_get_sys("tegra_emc", "emc");
if (IS_ERR(emc_clk)) {
cl_debug(DEBUG_TEGRADC,
"invalid clock specified when fetching EMC clock\n");
} else {
current_emc_freq = clk_get_rate(emc_clk);
current_emc_freq /= 1000;
max_available_bandwidth =
8 * tegra_emc_freq_req_to_bw(current_emc_freq);
max_available_bandwidth = (max_available_bandwidth / 100) * 50;
}
cl_debug(DEBUG_TEGRADC,
"b/w needed %lu, b/w available %lu\n",
max_bandwidth, max_available_bandwidth);
args->possible = (max_bandwidth <= max_available_bandwidth);
#else
ret = tegra_dc_bandwidth_negotiate_bw(dc, dc_wins, args->win_num);
args->possible = (ret == 0);
#endif
for (i = 0; i < args->win_num; i++) {
args->windows[i].bandwidth = dc_wins[i]->new_bandwidth;
cl_debug(DEBUG_TEGRADC,
"head %u, win %d, b/w %d\n",
args->head,
dc_wins[i]->idx,
dc_wins[i]->new_bandwidth);
}
LOG_EXT();
return 0;
}
int mods_init_tegradc(void)
{
return 0;
}