mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 01:50:07 +03:00
gpu: nvgpu: Move fuse override DT handling
Move fuse override DT handling to Linux code. All the chip specific fuse override functions did the same thing, so delete the HAL and call the same function to read the DT overrides on all chips. Also remove the fuse override functionality from dGPU. There are no DT entries for PCIe devices, so it would've failed anyway. JIRA NVGPU-259 Change-Id: Iba64a5d53bf4eb94198c0408a462620efc2ddde4 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1593687 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Deepak Nibade <dnibade@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
39527d5885
commit
1dad4adbd2
@@ -25,6 +25,8 @@
|
|||||||
#include <linux/reset.h>
|
#include <linux/reset.h>
|
||||||
#include <linux/platform/tegra/common.h>
|
#include <linux/platform/tegra/common.h>
|
||||||
#include <uapi/linux/nvgpu.h>
|
#include <uapi/linux/nvgpu.h>
|
||||||
|
#include <dt-bindings/soc/gm20b-fuse.h>
|
||||||
|
#include <dt-bindings/soc/gp10b-fuse.h>
|
||||||
|
|
||||||
#include <nvgpu/dma.h>
|
#include <nvgpu/dma.h>
|
||||||
#include <nvgpu/kmem.h>
|
#include <nvgpu/kmem.h>
|
||||||
@@ -994,6 +996,48 @@ static inline void set_gk20a(struct platform_device *pdev, struct gk20a *gk20a)
|
|||||||
gk20a_get_platform(&pdev->dev)->g = gk20a;
|
gk20a_get_platform(&pdev->dev)->g = gk20a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nvgpu_read_fuse_overrides(struct gk20a *g)
|
||||||
|
{
|
||||||
|
struct device_node *np = dev_from_gk20a(g)->of_node;
|
||||||
|
u32 *fuses;
|
||||||
|
int count, i;
|
||||||
|
|
||||||
|
if (!np) /* may be pcie device */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
count = of_property_count_elems_of_size(np, "fuse-overrides", 8);
|
||||||
|
if (count <= 0)
|
||||||
|
return count;
|
||||||
|
|
||||||
|
fuses = nvgpu_kmalloc(g, sizeof(u32) * count * 2);
|
||||||
|
if (!fuses)
|
||||||
|
return -ENOMEM;
|
||||||
|
of_property_read_u32_array(np, "fuse-overrides", fuses, count * 2);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
u32 fuse, value;
|
||||||
|
|
||||||
|
fuse = fuses[2 * i];
|
||||||
|
value = fuses[2 * i + 1];
|
||||||
|
switch (fuse) {
|
||||||
|
case GM20B_FUSE_OPT_TPC_DISABLE:
|
||||||
|
g->tpc_fs_mask_user = ~value;
|
||||||
|
break;
|
||||||
|
#ifdef CONFIG_ARCH_TEGRA_18x_SOC
|
||||||
|
case GP10B_FUSE_OPT_ECC_EN:
|
||||||
|
g->gr.t18x.fecs_feature_override_ecc_val = value;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
nvgpu_err(g, "ignore unknown fuse override %08x", fuse);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nvgpu_kfree(g, fuses);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int gk20a_probe(struct platform_device *dev)
|
static int gk20a_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
struct nvgpu_os_linux *l;
|
struct nvgpu_os_linux *l;
|
||||||
@@ -1077,6 +1121,8 @@ static int gk20a_probe(struct platform_device *dev)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
err = nvgpu_read_fuse_overrides(gk20a);
|
||||||
|
|
||||||
#ifdef CONFIG_RESET_CONTROLLER
|
#ifdef CONFIG_RESET_CONTROLLER
|
||||||
platform->reset_control = devm_reset_control_get(&dev->dev, NULL);
|
platform->reset_control = devm_reset_control_get(&dev->dev, NULL);
|
||||||
if (IS_ERR(platform->reset_control))
|
if (IS_ERR(platform->reset_control))
|
||||||
|
|||||||
@@ -385,7 +385,6 @@ struct gpu_ops {
|
|||||||
void (*update_boosted_ctx)(struct gk20a *g,
|
void (*update_boosted_ctx)(struct gk20a *g,
|
||||||
struct nvgpu_mem *mem,
|
struct nvgpu_mem *mem,
|
||||||
struct gr_ctx_desc *gr_ctx);
|
struct gr_ctx_desc *gr_ctx);
|
||||||
int (*fuse_override)(struct gk20a *g);
|
|
||||||
void (*init_sm_id_table)(struct gk20a *g);
|
void (*init_sm_id_table)(struct gk20a *g);
|
||||||
int (*load_smid_config)(struct gk20a *g);
|
int (*load_smid_config)(struct gk20a *g);
|
||||||
void (*program_sm_id_numbering)(struct gk20a *g,
|
void (*program_sm_id_numbering)(struct gk20a *g,
|
||||||
|
|||||||
@@ -4813,9 +4813,6 @@ static int gk20a_init_gr_setup_sw(struct gk20a *g)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g->ops.gr.fuse_override)
|
|
||||||
g->ops.gr.fuse_override(g);
|
|
||||||
|
|
||||||
gr->g = g;
|
gr->g = g;
|
||||||
|
|
||||||
#if defined(CONFIG_GK20A_CYCLE_STATS)
|
#if defined(CONFIG_GK20A_CYCLE_STATS)
|
||||||
|
|||||||
@@ -22,8 +22,6 @@
|
|||||||
* DEALINGS IN THE SOFTWARE.
|
* DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dt-bindings/soc/gm20b-fuse.h>
|
|
||||||
|
|
||||||
#include <nvgpu/kmem.h>
|
#include <nvgpu/kmem.h>
|
||||||
#include <nvgpu/log.h>
|
#include <nvgpu/log.h>
|
||||||
#include <nvgpu/enabled.h>
|
#include <nvgpu/enabled.h>
|
||||||
@@ -1423,52 +1421,6 @@ int gr_gm20b_get_preemption_mode_flags(struct gk20a *g,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gm20b_gr_tpc_disable_override(struct gk20a *g, u32 mask)
|
|
||||||
{
|
|
||||||
if (!mask)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
g->tpc_fs_mask_user = ~mask;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gm20b_gr_fuse_override(struct gk20a *g)
|
|
||||||
{
|
|
||||||
struct device_node *np = dev_from_gk20a(g)->of_node;
|
|
||||||
u32 *fuses;
|
|
||||||
int count, i;
|
|
||||||
|
|
||||||
if (!np) /* may be pcie device */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
count = of_property_count_elems_of_size(np, "fuse-overrides", 8);
|
|
||||||
if (count <= 0)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
fuses = nvgpu_kmalloc(g, sizeof(u32) * count * 2);
|
|
||||||
if (!fuses)
|
|
||||||
return -ENOMEM;
|
|
||||||
of_property_read_u32_array(np, "fuse-overrides", fuses, count * 2);
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
u32 fuse, value;
|
|
||||||
|
|
||||||
fuse = fuses[2 * i];
|
|
||||||
value = fuses[2 * i + 1];
|
|
||||||
switch (fuse) {
|
|
||||||
case GM20B_FUSE_OPT_TPC_DISABLE:
|
|
||||||
gm20b_gr_tpc_disable_override(g, value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
nvgpu_err(g, "ignore unknown fuse override %08x", fuse);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nvgpu_kfree(g, fuses);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gr_gm20b_is_ltcs_ltss_addr(struct gk20a *g, u32 addr)
|
bool gr_gm20b_is_ltcs_ltss_addr(struct gk20a *g, u32 addr)
|
||||||
{
|
{
|
||||||
u32 ltc_shared_base = ltc_ltcs_ltss_v();
|
u32 ltc_shared_base = ltc_ltcs_ltss_v();
|
||||||
|
|||||||
@@ -124,7 +124,6 @@ int gm20b_gr_clear_sm_error_state(struct gk20a *g,
|
|||||||
struct channel_gk20a *ch, u32 sm_id);
|
struct channel_gk20a *ch, u32 sm_id);
|
||||||
int gr_gm20b_get_preemption_mode_flags(struct gk20a *g,
|
int gr_gm20b_get_preemption_mode_flags(struct gk20a *g,
|
||||||
struct nvgpu_preemption_modes_rec *preemption_modes_rec);
|
struct nvgpu_preemption_modes_rec *preemption_modes_rec);
|
||||||
int gm20b_gr_fuse_override(struct gk20a *g);
|
|
||||||
bool gr_gm20b_is_ltcs_ltss_addr(struct gk20a *g, u32 addr);
|
bool gr_gm20b_is_ltcs_ltss_addr(struct gk20a *g, u32 addr);
|
||||||
bool gr_gm20b_is_ltcn_ltss_addr(struct gk20a *g, u32 addr);
|
bool gr_gm20b_is_ltcn_ltss_addr(struct gk20a *g, u32 addr);
|
||||||
void gr_gm20b_split_lts_broadcast_addr(struct gk20a *g, u32 addr,
|
void gr_gm20b_split_lts_broadcast_addr(struct gk20a *g, u32 addr,
|
||||||
|
|||||||
@@ -254,7 +254,6 @@ static const struct gpu_ops gm20b_ops = {
|
|||||||
.suspend_contexts = gr_gk20a_suspend_contexts,
|
.suspend_contexts = gr_gk20a_suspend_contexts,
|
||||||
.resume_contexts = gr_gk20a_resume_contexts,
|
.resume_contexts = gr_gk20a_resume_contexts,
|
||||||
.get_preemption_mode_flags = gr_gm20b_get_preemption_mode_flags,
|
.get_preemption_mode_flags = gr_gm20b_get_preemption_mode_flags,
|
||||||
.fuse_override = gm20b_gr_fuse_override,
|
|
||||||
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
||||||
.load_smid_config = gr_gm20b_load_smid_config,
|
.load_smid_config = gr_gm20b_load_smid_config,
|
||||||
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
||||||
|
|||||||
@@ -300,7 +300,6 @@ static const struct gpu_ops gp106_ops = {
|
|||||||
.suspend_contexts = gr_gp10b_suspend_contexts,
|
.suspend_contexts = gr_gp10b_suspend_contexts,
|
||||||
.resume_contexts = gr_gk20a_resume_contexts,
|
.resume_contexts = gr_gk20a_resume_contexts,
|
||||||
.get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags,
|
.get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags,
|
||||||
.fuse_override = gp10b_gr_fuse_override,
|
|
||||||
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
||||||
.load_smid_config = gr_gp10b_load_smid_config,
|
.load_smid_config = gr_gp10b_load_smid_config,
|
||||||
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
||||||
|
|||||||
@@ -2291,45 +2291,6 @@ int gr_gp10b_get_preemption_mode_flags(struct gk20a *g,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int gp10b_gr_fuse_override(struct gk20a *g)
|
|
||||||
{
|
|
||||||
struct device_node *np = dev_from_gk20a(g)->of_node;
|
|
||||||
u32 *fuses;
|
|
||||||
int count, i;
|
|
||||||
|
|
||||||
if (!np) /* may be pcie device */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
count = of_property_count_elems_of_size(np, "fuse-overrides", 8);
|
|
||||||
if (count <= 0)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
fuses = nvgpu_kmalloc(g, sizeof(u32) * count * 2);
|
|
||||||
if (!fuses)
|
|
||||||
return -ENOMEM;
|
|
||||||
of_property_read_u32_array(np, "fuse-overrides", fuses, count * 2);
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
u32 fuse, value;
|
|
||||||
|
|
||||||
fuse = fuses[2 * i];
|
|
||||||
value = fuses[2 * i + 1];
|
|
||||||
switch (fuse) {
|
|
||||||
case GM20B_FUSE_OPT_TPC_DISABLE:
|
|
||||||
gm20b_gr_tpc_disable_override(g, value);
|
|
||||||
break;
|
|
||||||
case GP10B_FUSE_OPT_ECC_EN:
|
|
||||||
g->gr.t18x.fecs_feature_override_ecc_val = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
nvgpu_err(g, "ignore unknown fuse override %08x", fuse);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nvgpu_kfree(g, fuses);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gr_gp10b_init_preemption_state(struct gk20a *g)
|
int gr_gp10b_init_preemption_state(struct gk20a *g)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -263,7 +263,6 @@ static const struct gpu_ops gp10b_ops = {
|
|||||||
.suspend_contexts = gr_gp10b_suspend_contexts,
|
.suspend_contexts = gr_gp10b_suspend_contexts,
|
||||||
.resume_contexts = gr_gk20a_resume_contexts,
|
.resume_contexts = gr_gk20a_resume_contexts,
|
||||||
.get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags,
|
.get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags,
|
||||||
.fuse_override = gp10b_gr_fuse_override,
|
|
||||||
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
||||||
.load_smid_config = gr_gp10b_load_smid_config,
|
.load_smid_config = gr_gp10b_load_smid_config,
|
||||||
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ static const struct gpu_ops vgpu_gm20b_ops = {
|
|||||||
.suspend_contexts = vgpu_gr_suspend_contexts,
|
.suspend_contexts = vgpu_gr_suspend_contexts,
|
||||||
.resume_contexts = vgpu_gr_resume_contexts,
|
.resume_contexts = vgpu_gr_resume_contexts,
|
||||||
.get_preemption_mode_flags = gr_gm20b_get_preemption_mode_flags,
|
.get_preemption_mode_flags = gr_gm20b_get_preemption_mode_flags,
|
||||||
.fuse_override = gm20b_gr_fuse_override,
|
|
||||||
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
||||||
.load_smid_config = gr_gm20b_load_smid_config,
|
.load_smid_config = gr_gm20b_load_smid_config,
|
||||||
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
||||||
|
|||||||
@@ -163,7 +163,6 @@ static const struct gpu_ops vgpu_gp10b_ops = {
|
|||||||
.suspend_contexts = vgpu_gr_suspend_contexts,
|
.suspend_contexts = vgpu_gr_suspend_contexts,
|
||||||
.resume_contexts = vgpu_gr_resume_contexts,
|
.resume_contexts = vgpu_gr_resume_contexts,
|
||||||
.get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags,
|
.get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags,
|
||||||
.fuse_override = gp10b_gr_fuse_override,
|
|
||||||
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
.init_sm_id_table = gr_gk20a_init_sm_id_table,
|
||||||
.load_smid_config = gr_gp10b_load_smid_config,
|
.load_smid_config = gr_gp10b_load_smid_config,
|
||||||
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
.program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
|
||||||
|
|||||||
Reference in New Issue
Block a user