Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
9422644d
Commit
9422644d
authored
May 16, 2023
by
Thierry Reding
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-6.5/memory' into for-6.5/pci
parents
ac9a7868
e852af72
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
835 additions
and
1 deletion
+835
-1
Documentation/devicetree/bindings/arm/tegra.yaml
Documentation/devicetree/bindings/arm/tegra.yaml
+5
-0
drivers/memory/tegra/mc.c
drivers/memory/tegra/mc.c
+24
-0
drivers/memory/tegra/mc.h
drivers/memory/tegra/mc.h
+1
-0
drivers/memory/tegra/tegra186-emc.c
drivers/memory/tegra/tegra186-emc.c
+133
-0
drivers/memory/tegra/tegra234.c
drivers/memory/tegra/tegra234.c
+594
-1
include/dt-bindings/memory/tegra234-mc.h
include/dt-bindings/memory/tegra234-mc.h
+5
-0
include/linux/tegra-icc.h
include/linux/tegra-icc.h
+65
-0
include/soc/tegra/mc.h
include/soc/tegra/mc.h
+8
-0
No files found.
Documentation/devicetree/bindings/arm/tegra.yaml
View file @
9422644d
...
...
@@ -167,6 +167,11 @@ properties:
-
const
:
nvidia,p3737-0000+p3701-0000
-
const
:
nvidia,p3701-0000
-
const
:
nvidia,tegra234
-
description
:
NVIDIA IGX Orin Development Kit
items
:
-
const
:
nvidia,p3740-0002+p3701-0008
-
const
:
nvidia,p3701-0008
-
const
:
nvidia,tegra234
-
description
:
Jetson Orin NX
items
:
-
const
:
nvidia,p3767-0000
...
...
drivers/memory/tegra/mc.c
View file @
9422644d
...
...
@@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/sort.h>
#include <linux/tegra-icc.h>
#include <soc/tegra/fuse.h>
...
...
@@ -792,6 +793,8 @@ static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
mc
->
provider
.
data
=
&
mc
->
provider
;
mc
->
provider
.
set
=
mc
->
soc
->
icc_ops
->
set
;
mc
->
provider
.
aggregate
=
mc
->
soc
->
icc_ops
->
aggregate
;
mc
->
provider
.
get_bw
=
mc
->
soc
->
icc_ops
->
get_bw
;
mc
->
provider
.
xlate
=
mc
->
soc
->
icc_ops
->
xlate
;
mc
->
provider
.
xlate_extended
=
mc
->
soc
->
icc_ops
->
xlate_extended
;
icc_provider_init
(
&
mc
->
provider
);
...
...
@@ -824,6 +827,8 @@ static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
err
=
icc_link_create
(
node
,
TEGRA_ICC_MC
);
if
(
err
)
goto
remove_nodes
;
node
->
data
=
(
struct
tegra_mc_client
*
)
&
(
mc
->
soc
->
clients
[
i
]);
}
err
=
icc_provider_register
(
&
mc
->
provider
);
...
...
@@ -838,6 +843,23 @@ static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
return
err
;
}
static
void
tegra_mc_num_channel_enabled
(
struct
tegra_mc
*
mc
)
{
unsigned
int
i
;
u32
value
;
value
=
mc_ch_readl
(
mc
,
0
,
MC_EMEM_ADR_CFG_CHANNEL_ENABLE
);
if
(
value
<=
0
)
{
mc
->
num_channels
=
mc
->
soc
->
num_channels
;
return
;
}
for
(
i
=
0
;
i
<
32
;
i
++
)
{
if
(
value
&
BIT
(
i
))
mc
->
num_channels
++
;
}
}
static
int
tegra_mc_probe
(
struct
platform_device
*
pdev
)
{
struct
tegra_mc
*
mc
;
...
...
@@ -876,6 +898,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
return
err
;
}
tegra_mc_num_channel_enabled
(
mc
);
if
(
mc
->
soc
->
ops
&&
mc
->
soc
->
ops
->
handle_irq
)
{
mc
->
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
mc
->
irq
<
0
)
...
...
drivers/memory/tegra/mc.h
View file @
9422644d
...
...
@@ -53,6 +53,7 @@
#define MC_ERR_ROUTE_SANITY_ADR 0x9c4
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
#define MC_EMEM_ADR_CFG_CHANNEL_ENABLE 0xdf8
#define MC_GLOBAL_INTSTATUS 0xf24
#define MC_ERR_ADR_HI 0x11fc
...
...
drivers/memory/tegra/tegra186-emc.c
View file @
9422644d
...
...
@@ -7,9 +7,11 @@
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <soc/tegra/bpmp.h>
#include "mc.h"
struct
tegra186_emc_dvfs
{
unsigned
long
latency
;
...
...
@@ -29,8 +31,15 @@ struct tegra186_emc {
unsigned
long
min_rate
;
unsigned
long
max_rate
;
}
debugfs
;
struct
icc_provider
provider
;
};
static
inline
struct
tegra186_emc
*
to_tegra186_emc
(
struct
icc_provider
*
provider
)
{
return
container_of
(
provider
,
struct
tegra186_emc
,
provider
);
}
/*
* debugfs interface
*
...
...
@@ -146,8 +155,102 @@ DEFINE_DEBUGFS_ATTRIBUTE(tegra186_emc_debug_max_rate_fops,
tegra186_emc_debug_max_rate_get
,
tegra186_emc_debug_max_rate_set
,
"%llu
\n
"
);
/*
* tegra_emc_icc_set_bw() - Set BW api for EMC provider
* @src: ICC node for External Memory Controller (EMC)
* @dst: ICC node for External Memory (DRAM)
*
* Do nothing here as info to BPMP-FW is now passed in the BW set function
* of the MC driver. BPMP-FW sets the final Freq based on the passed values.
*/
static
int
tegra_emc_icc_set_bw
(
struct
icc_node
*
src
,
struct
icc_node
*
dst
)
{
return
0
;
}
static
struct
icc_node
*
tegra_emc_of_icc_xlate
(
struct
of_phandle_args
*
spec
,
void
*
data
)
{
struct
icc_provider
*
provider
=
data
;
struct
icc_node
*
node
;
/* External Memory is the only possible ICC route */
list_for_each_entry
(
node
,
&
provider
->
nodes
,
node_list
)
{
if
(
node
->
id
!=
TEGRA_ICC_EMEM
)
continue
;
return
node
;
}
return
ERR_PTR
(
-
EPROBE_DEFER
);
}
static
int
tegra_emc_icc_get_init_bw
(
struct
icc_node
*
node
,
u32
*
avg
,
u32
*
peak
)
{
*
avg
=
0
;
*
peak
=
0
;
return
0
;
}
static
int
tegra_emc_interconnect_init
(
struct
tegra186_emc
*
emc
)
{
struct
tegra_mc
*
mc
=
dev_get_drvdata
(
emc
->
dev
->
parent
);
const
struct
tegra_mc_soc
*
soc
=
mc
->
soc
;
struct
icc_node
*
node
;
int
err
;
emc
->
provider
.
dev
=
emc
->
dev
;
emc
->
provider
.
set
=
tegra_emc_icc_set_bw
;
emc
->
provider
.
data
=
&
emc
->
provider
;
emc
->
provider
.
aggregate
=
soc
->
icc_ops
->
aggregate
;
emc
->
provider
.
xlate
=
tegra_emc_of_icc_xlate
;
emc
->
provider
.
get_bw
=
tegra_emc_icc_get_init_bw
;
icc_provider_init
(
&
emc
->
provider
);
/* create External Memory Controller node */
node
=
icc_node_create
(
TEGRA_ICC_EMC
);
if
(
IS_ERR
(
node
))
{
err
=
PTR_ERR
(
node
);
goto
err_msg
;
}
node
->
name
=
"External Memory Controller"
;
icc_node_add
(
node
,
&
emc
->
provider
);
/* link External Memory Controller to External Memory (DRAM) */
err
=
icc_link_create
(
node
,
TEGRA_ICC_EMEM
);
if
(
err
)
goto
remove_nodes
;
/* create External Memory node */
node
=
icc_node_create
(
TEGRA_ICC_EMEM
);
if
(
IS_ERR
(
node
))
{
err
=
PTR_ERR
(
node
);
goto
remove_nodes
;
}
node
->
name
=
"External Memory (DRAM)"
;
icc_node_add
(
node
,
&
emc
->
provider
);
err
=
icc_provider_register
(
&
emc
->
provider
);
if
(
err
)
goto
remove_nodes
;
return
0
;
remove_nodes:
icc_nodes_remove
(
&
emc
->
provider
);
err_msg:
dev_err
(
emc
->
dev
,
"failed to initialize ICC: %d
\n
"
,
err
);
return
err
;
}
static
int
tegra186_emc_probe
(
struct
platform_device
*
pdev
)
{
struct
tegra_mc
*
mc
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
mrq_emc_dvfs_latency_response
response
;
struct
tegra_bpmp_message
msg
;
struct
tegra186_emc
*
emc
;
...
...
@@ -236,6 +339,32 @@ static int tegra186_emc_probe(struct platform_device *pdev)
debugfs_create_file
(
"max_rate"
,
S_IRUGO
|
S_IWUSR
,
emc
->
debugfs
.
root
,
emc
,
&
tegra186_emc_debug_max_rate_fops
);
if
(
mc
&&
mc
->
soc
->
icc_ops
)
{
if
(
tegra_bpmp_mrq_is_supported
(
emc
->
bpmp
,
MRQ_BWMGR_INT
))
{
mc
->
bwmgr_mrq_supported
=
true
;
/*
* MC driver probe can't get BPMP reference as it gets probed
* earlier than BPMP. So, save the BPMP ref got from the EMC
* DT node in the mc->bpmp and use it in MC's icc_set hook.
*/
mc
->
bpmp
=
emc
->
bpmp
;
barrier
();
}
/*
* Initialize the ICC even if BPMP-FW doesn't support 'MRQ_BWMGR_INT'.
* Use the flag 'mc->bwmgr_mrq_supported' within MC driver and return
* EINVAL instead of passing the request to BPMP-FW later when the BW
* request is made by client with 'icc_set_bw()' call.
*/
err
=
tegra_emc_interconnect_init
(
emc
);
if
(
err
)
{
mc
->
bpmp
=
NULL
;
goto
put_bpmp
;
}
}
return
0
;
put_bpmp:
...
...
@@ -245,9 +374,12 @@ static int tegra186_emc_probe(struct platform_device *pdev)
static
int
tegra186_emc_remove
(
struct
platform_device
*
pdev
)
{
struct
tegra_mc
*
mc
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
tegra186_emc
*
emc
=
platform_get_drvdata
(
pdev
);
debugfs_remove_recursive
(
emc
->
debugfs
.
root
);
mc
->
bpmp
=
NULL
;
tegra_bpmp_put
(
emc
->
bpmp
);
return
0
;
...
...
@@ -272,6 +404,7 @@ static struct platform_driver tegra186_emc_driver = {
.
name
=
"tegra186-emc"
,
.
of_match_table
=
tegra186_emc_of_match
,
.
suppress_bind_attrs
=
true
,
.
sync_state
=
icc_sync_state
,
},
.
probe
=
tegra186_emc_probe
,
.
remove
=
tegra186_emc_remove
,
...
...
drivers/memory/tegra/tegra234.c
View file @
9422644d
This diff is collapsed.
Click to expand it.
include/dt-bindings/memory/tegra234-mc.h
View file @
9422644d
...
...
@@ -536,4 +536,9 @@
#define TEGRA234_MEMORY_CLIENT_NVJPG1SRD 0x123
#define TEGRA234_MEMORY_CLIENT_NVJPG1SWR 0x124
/* ICC ID's for dummy MC clients used to represent CPU Clusters */
#define TEGRA_ICC_MC_CPU_CLUSTER0 1003
#define TEGRA_ICC_MC_CPU_CLUSTER1 1004
#define TEGRA_ICC_MC_CPU_CLUSTER2 1005
#endif
include/linux/tegra-icc.h
0 → 100644
View file @
9422644d
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2022-2023 NVIDIA CORPORATION. All rights reserved.
*/
#ifndef LINUX_TEGRA_ICC_H
#define LINUX_TEGRA_ICC_H
enum
tegra_icc_client_type
{
TEGRA_ICC_NONE
,
TEGRA_ICC_NISO
,
TEGRA_ICC_ISO_DISPLAY
,
TEGRA_ICC_ISO_VI
,
TEGRA_ICC_ISO_AUDIO
,
TEGRA_ICC_ISO_VIFAL
,
};
/* ICC ID's for MC client's used in BPMP */
#define TEGRA_ICC_BPMP_DEBUG 1
#define TEGRA_ICC_BPMP_CPU_CLUSTER0 2
#define TEGRA_ICC_BPMP_CPU_CLUSTER1 3
#define TEGRA_ICC_BPMP_CPU_CLUSTER2 4
#define TEGRA_ICC_BPMP_GPU 5
#define TEGRA_ICC_BPMP_CACTMON 6
#define TEGRA_ICC_BPMP_DISPLAY 7
#define TEGRA_ICC_BPMP_VI 8
#define TEGRA_ICC_BPMP_EQOS 9
#define TEGRA_ICC_BPMP_PCIE_0 10
#define TEGRA_ICC_BPMP_PCIE_1 11
#define TEGRA_ICC_BPMP_PCIE_2 12
#define TEGRA_ICC_BPMP_PCIE_3 13
#define TEGRA_ICC_BPMP_PCIE_4 14
#define TEGRA_ICC_BPMP_PCIE_5 15
#define TEGRA_ICC_BPMP_PCIE_6 16
#define TEGRA_ICC_BPMP_PCIE_7 17
#define TEGRA_ICC_BPMP_PCIE_8 18
#define TEGRA_ICC_BPMP_PCIE_9 19
#define TEGRA_ICC_BPMP_PCIE_10 20
#define TEGRA_ICC_BPMP_DLA_0 21
#define TEGRA_ICC_BPMP_DLA_1 22
#define TEGRA_ICC_BPMP_SDMMC_1 23
#define TEGRA_ICC_BPMP_SDMMC_2 24
#define TEGRA_ICC_BPMP_SDMMC_3 25
#define TEGRA_ICC_BPMP_SDMMC_4 26
#define TEGRA_ICC_BPMP_NVDEC 27
#define TEGRA_ICC_BPMP_NVENC 28
#define TEGRA_ICC_BPMP_NVJPG_0 29
#define TEGRA_ICC_BPMP_NVJPG_1 30
#define TEGRA_ICC_BPMP_OFAA 31
#define TEGRA_ICC_BPMP_XUSB_HOST 32
#define TEGRA_ICC_BPMP_XUSB_DEV 33
#define TEGRA_ICC_BPMP_TSEC 34
#define TEGRA_ICC_BPMP_VIC 35
#define TEGRA_ICC_BPMP_APE 36
#define TEGRA_ICC_BPMP_APEDMA 37
#define TEGRA_ICC_BPMP_SE 38
#define TEGRA_ICC_BPMP_ISP 39
#define TEGRA_ICC_BPMP_HDA 40
#define TEGRA_ICC_BPMP_VIFAL 41
#define TEGRA_ICC_BPMP_VI2FAL 42
#define TEGRA_ICC_BPMP_VI2 43
#define TEGRA_ICC_BPMP_RCE 44
#define TEGRA_ICC_BPMP_PVA 45
#endif
/* LINUX_TEGRA_ICC_H */
include/soc/tegra/mc.h
View file @
9422644d
...
...
@@ -13,6 +13,7 @@
#include <linux/irq.h>
#include <linux/reset-controller.h>
#include <linux/types.h>
#include <linux/tegra-icc.h>
struct
clk
;
struct
device
;
...
...
@@ -26,6 +27,8 @@ struct tegra_mc_timing {
struct
tegra_mc_client
{
unsigned
int
id
;
unsigned
int
bpmp_id
;
enum
tegra_icc_client_type
type
;
const
char
*
name
;
/*
* For Tegra210 and earlier, this is the SWGROUP ID used for IOVA translations in the
...
...
@@ -166,8 +169,10 @@ struct tegra_mc_icc_ops {
int
(
*
set
)(
struct
icc_node
*
src
,
struct
icc_node
*
dst
);
int
(
*
aggregate
)(
struct
icc_node
*
node
,
u32
tag
,
u32
avg_bw
,
u32
peak_bw
,
u32
*
agg_avg
,
u32
*
agg_peak
);
struct
icc_node
*
(
*
xlate
)(
struct
of_phandle_args
*
spec
,
void
*
data
);
struct
icc_node_data
*
(
*
xlate_extended
)(
struct
of_phandle_args
*
spec
,
void
*
data
);
int
(
*
get_bw
)(
struct
icc_node
*
node
,
u32
*
avg
,
u32
*
peak
);
};
struct
tegra_mc_ops
{
...
...
@@ -214,6 +219,7 @@ struct tegra_mc_soc {
};
struct
tegra_mc
{
struct
tegra_bpmp
*
bpmp
;
struct
device
*
dev
;
struct
tegra_smmu
*
smmu
;
struct
gart_device
*
gart
;
...
...
@@ -228,7 +234,9 @@ struct tegra_mc {
struct
tegra_mc_timing
*
timings
;
unsigned
int
num_timings
;
unsigned
int
num_channels
;
bool
bwmgr_mrq_supported
;
struct
reset_controller_dev
reset
;
struct
icc_provider
provider
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment