2017-12-13 14:58:21 +03:00
/*
* Copyright ( C ) 2017 NVIDIA CORPORATION . All rights reserved .
*
* This program 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 .
*/
# include <linux/io.h>
# include <linux/module.h>
2018-06-20 08:47:28 +03:00
# include <linux/mod_devicetable.h>
2017-12-13 14:58:21 +03:00
# include <linux/platform_device.h>
# include <dt-bindings/memory/tegra186-mc.h>
struct tegra_mc {
struct device * dev ;
void __iomem * regs ;
} ;
struct tegra_mc_client {
const char * name ;
unsigned int sid ;
struct {
unsigned int override ;
unsigned int security ;
} regs ;
} ;
static const struct tegra_mc_client tegra186_mc_clients [ ] = {
{
. name = " ptcr " ,
. sid = TEGRA186_SID_PASSTHROUGH ,
. regs = {
. override = 0x000 ,
. security = 0x004 ,
} ,
} , {
. name = " afir " ,
. sid = TEGRA186_SID_AFI ,
. regs = {
. override = 0x070 ,
. security = 0x074 ,
} ,
} , {
. name = " hdar " ,
. sid = TEGRA186_SID_HDA ,
. regs = {
. override = 0x0a8 ,
. security = 0x0ac ,
} ,
} , {
. name = " host1xdmar " ,
. sid = TEGRA186_SID_HOST1X ,
. regs = {
. override = 0x0b0 ,
. security = 0x0b4 ,
} ,
} , {
. name = " nvencsrd " ,
. sid = TEGRA186_SID_NVENC ,
. regs = {
. override = 0x0e0 ,
. security = 0x0e4 ,
} ,
} , {
. name = " satar " ,
. sid = TEGRA186_SID_SATA ,
. regs = {
. override = 0x0f8 ,
. security = 0x0fc ,
} ,
} , {
. name = " mpcorer " ,
. sid = TEGRA186_SID_PASSTHROUGH ,
. regs = {
. override = 0x138 ,
. security = 0x13c ,
} ,
} , {
. name = " nvencswr " ,
. sid = TEGRA186_SID_NVENC ,
. regs = {
. override = 0x158 ,
. security = 0x15c ,
} ,
} , {
. name = " afiw " ,
. sid = TEGRA186_SID_AFI ,
. regs = {
. override = 0x188 ,
. security = 0x18c ,
} ,
} , {
. name = " hdaw " ,
. sid = TEGRA186_SID_HDA ,
. regs = {
. override = 0x1a8 ,
. security = 0x1ac ,
} ,
} , {
. name = " mpcorew " ,
. sid = TEGRA186_SID_PASSTHROUGH ,
. regs = {
. override = 0x1c8 ,
. security = 0x1cc ,
} ,
} , {
. name = " sataw " ,
. sid = TEGRA186_SID_SATA ,
. regs = {
. override = 0x1e8 ,
. security = 0x1ec ,
} ,
} , {
. name = " ispra " ,
. sid = TEGRA186_SID_ISP ,
. regs = {
. override = 0x220 ,
. security = 0x224 ,
} ,
} , {
. name = " ispwa " ,
. sid = TEGRA186_SID_ISP ,
. regs = {
. override = 0x230 ,
. security = 0x234 ,
} ,
} , {
. name = " ispwb " ,
. sid = TEGRA186_SID_ISP ,
. regs = {
. override = 0x238 ,
. security = 0x23c ,
} ,
} , {
. name = " xusb_hostr " ,
. sid = TEGRA186_SID_XUSB_HOST ,
. regs = {
. override = 0x250 ,
. security = 0x254 ,
} ,
} , {
. name = " xusb_hostw " ,
. sid = TEGRA186_SID_XUSB_HOST ,
. regs = {
. override = 0x258 ,
. security = 0x25c ,
} ,
} , {
. name = " xusb_devr " ,
. sid = TEGRA186_SID_XUSB_DEV ,
. regs = {
. override = 0x260 ,
. security = 0x264 ,
} ,
} , {
. name = " xusb_devw " ,
. sid = TEGRA186_SID_XUSB_DEV ,
. regs = {
. override = 0x268 ,
. security = 0x26c ,
} ,
} , {
. name = " tsecsrd " ,
. sid = TEGRA186_SID_TSEC ,
. regs = {
. override = 0x2a0 ,
. security = 0x2a4 ,
} ,
} , {
. name = " tsecswr " ,
. sid = TEGRA186_SID_TSEC ,
. regs = {
. override = 0x2a8 ,
. security = 0x2ac ,
} ,
} , {
. name = " gpusrd " ,
. sid = TEGRA186_SID_GPU ,
. regs = {
. override = 0x2c0 ,
. security = 0x2c4 ,
} ,
} , {
. name = " gpuswr " ,
. sid = TEGRA186_SID_GPU ,
. regs = {
. override = 0x2c8 ,
. security = 0x2cc ,
} ,
} , {
. name = " sdmmcra " ,
. sid = TEGRA186_SID_SDMMC1 ,
. regs = {
. override = 0x300 ,
. security = 0x304 ,
} ,
} , {
. name = " sdmmcraa " ,
. sid = TEGRA186_SID_SDMMC2 ,
. regs = {
. override = 0x308 ,
. security = 0x30c ,
} ,
} , {
. name = " sdmmcr " ,
. sid = TEGRA186_SID_SDMMC3 ,
. regs = {
. override = 0x310 ,
. security = 0x314 ,
} ,
} , {
. name = " sdmmcrab " ,
. sid = TEGRA186_SID_SDMMC4 ,
. regs = {
. override = 0x318 ,
. security = 0x31c ,
} ,
} , {
. name = " sdmmcwa " ,
. sid = TEGRA186_SID_SDMMC1 ,
. regs = {
. override = 0x320 ,
. security = 0x324 ,
} ,
} , {
. name = " sdmmcwaa " ,
. sid = TEGRA186_SID_SDMMC2 ,
. regs = {
. override = 0x328 ,
. security = 0x32c ,
} ,
} , {
. name = " sdmmcw " ,
. sid = TEGRA186_SID_SDMMC3 ,
. regs = {
. override = 0x330 ,
. security = 0x334 ,
} ,
} , {
. name = " sdmmcwab " ,
. sid = TEGRA186_SID_SDMMC4 ,
. regs = {
. override = 0x338 ,
. security = 0x33c ,
} ,
} , {
. name = " vicsrd " ,
. sid = TEGRA186_SID_VIC ,
. regs = {
. override = 0x360 ,
. security = 0x364 ,
} ,
} , {
. name = " vicswr " ,
. sid = TEGRA186_SID_VIC ,
. regs = {
. override = 0x368 ,
. security = 0x36c ,
} ,
} , {
. name = " viw " ,
. sid = TEGRA186_SID_VI ,
. regs = {
. override = 0x390 ,
. security = 0x394 ,
} ,
} , {
. name = " nvdecsrd " ,
. sid = TEGRA186_SID_NVDEC ,
. regs = {
. override = 0x3c0 ,
. security = 0x3c4 ,
} ,
} , {
. name = " nvdecswr " ,
. sid = TEGRA186_SID_NVDEC ,
. regs = {
. override = 0x3c8 ,
. security = 0x3cc ,
} ,
} , {
. name = " aper " ,
. sid = TEGRA186_SID_APE ,
. regs = {
. override = 0x3d0 ,
. security = 0x3d4 ,
} ,
} , {
. name = " apew " ,
. sid = TEGRA186_SID_APE ,
. regs = {
. override = 0x3d8 ,
. security = 0x3dc ,
} ,
} , {
. name = " nvjpgsrd " ,
. sid = TEGRA186_SID_NVJPG ,
. regs = {
. override = 0x3f0 ,
. security = 0x3f4 ,
} ,
} , {
. name = " nvjpgswr " ,
. sid = TEGRA186_SID_NVJPG ,
. regs = {
. override = 0x3f8 ,
. security = 0x3fc ,
} ,
} , {
. name = " sesrd " ,
. sid = TEGRA186_SID_SE ,
. regs = {
. override = 0x400 ,
. security = 0x404 ,
} ,
} , {
. name = " seswr " ,
. sid = TEGRA186_SID_SE ,
. regs = {
. override = 0x408 ,
. security = 0x40c ,
} ,
} , {
. name = " etrr " ,
. sid = TEGRA186_SID_ETR ,
. regs = {
. override = 0x420 ,
. security = 0x424 ,
} ,
} , {
. name = " etrw " ,
. sid = TEGRA186_SID_ETR ,
. regs = {
. override = 0x428 ,
. security = 0x42c ,
} ,
} , {
. name = " tsecsrdb " ,
. sid = TEGRA186_SID_TSECB ,
. regs = {
. override = 0x430 ,
. security = 0x434 ,
} ,
} , {
. name = " tsecswrb " ,
. sid = TEGRA186_SID_TSECB ,
. regs = {
. override = 0x438 ,
. security = 0x43c ,
} ,
} , {
. name = " gpusrd2 " ,
. sid = TEGRA186_SID_GPU ,
. regs = {
. override = 0x440 ,
. security = 0x444 ,
} ,
} , {
. name = " gpuswr2 " ,
. sid = TEGRA186_SID_GPU ,
. regs = {
. override = 0x448 ,
. security = 0x44c ,
} ,
} , {
. name = " axisr " ,
. sid = TEGRA186_SID_GPCDMA_0 ,
. regs = {
. override = 0x460 ,
. security = 0x464 ,
} ,
} , {
. name = " axisw " ,
. sid = TEGRA186_SID_GPCDMA_0 ,
. regs = {
. override = 0x468 ,
. security = 0x46c ,
} ,
} , {
. name = " eqosr " ,
. sid = TEGRA186_SID_EQOS ,
. regs = {
. override = 0x470 ,
. security = 0x474 ,
} ,
} , {
. name = " eqosw " ,
. sid = TEGRA186_SID_EQOS ,
. regs = {
. override = 0x478 ,
. security = 0x47c ,
} ,
} , {
. name = " ufshcr " ,
. sid = TEGRA186_SID_UFSHC ,
. regs = {
. override = 0x480 ,
. security = 0x484 ,
} ,
} , {
. name = " ufshcw " ,
. sid = TEGRA186_SID_UFSHC ,
. regs = {
. override = 0x488 ,
. security = 0x48c ,
} ,
} , {
. name = " nvdisplayr " ,
. sid = TEGRA186_SID_NVDISPLAY ,
. regs = {
. override = 0x490 ,
. security = 0x494 ,
} ,
} , {
. name = " bpmpr " ,
. sid = TEGRA186_SID_BPMP ,
. regs = {
. override = 0x498 ,
. security = 0x49c ,
} ,
} , {
. name = " bpmpw " ,
. sid = TEGRA186_SID_BPMP ,
. regs = {
. override = 0x4a0 ,
. security = 0x4a4 ,
} ,
} , {
. name = " bpmpdmar " ,
. sid = TEGRA186_SID_BPMP ,
. regs = {
. override = 0x4a8 ,
. security = 0x4ac ,
} ,
} , {
. name = " bpmpdmaw " ,
. sid = TEGRA186_SID_BPMP ,
. regs = {
. override = 0x4b0 ,
. security = 0x4b4 ,
} ,
} , {
. name = " aonr " ,
. sid = TEGRA186_SID_AON ,
. regs = {
. override = 0x4b8 ,
. security = 0x4bc ,
} ,
} , {
. name = " aonw " ,
. sid = TEGRA186_SID_AON ,
. regs = {
. override = 0x4c0 ,
. security = 0x4c4 ,
} ,
} , {
. name = " aondmar " ,
. sid = TEGRA186_SID_AON ,
. regs = {
. override = 0x4c8 ,
. security = 0x4cc ,
} ,
} , {
. name = " aondmaw " ,
. sid = TEGRA186_SID_AON ,
. regs = {
. override = 0x4d0 ,
. security = 0x4d4 ,
} ,
} , {
. name = " scer " ,
. sid = TEGRA186_SID_SCE ,
. regs = {
. override = 0x4d8 ,
. security = 0x4dc ,
} ,
} , {
. name = " scew " ,
. sid = TEGRA186_SID_SCE ,
. regs = {
. override = 0x4e0 ,
. security = 0x4e4 ,
} ,
} , {
. name = " scedmar " ,
. sid = TEGRA186_SID_SCE ,
. regs = {
. override = 0x4e8 ,
. security = 0x4ec ,
} ,
} , {
. name = " scedmaw " ,
. sid = TEGRA186_SID_SCE ,
. regs = {
. override = 0x4f0 ,
. security = 0x4f4 ,
} ,
} , {
. name = " apedmar " ,
. sid = TEGRA186_SID_APE ,
. regs = {
. override = 0x4f8 ,
. security = 0x4fc ,
} ,
} , {
. name = " apedmaw " ,
. sid = TEGRA186_SID_APE ,
. regs = {
. override = 0x500 ,
. security = 0x504 ,
} ,
} , {
. name = " nvdisplayr1 " ,
. sid = TEGRA186_SID_NVDISPLAY ,
. regs = {
. override = 0x508 ,
. security = 0x50c ,
} ,
} , {
. name = " vicsrd1 " ,
. sid = TEGRA186_SID_VIC ,
. regs = {
. override = 0x510 ,
. security = 0x514 ,
} ,
} , {
. name = " nvdecsrd1 " ,
. sid = TEGRA186_SID_NVDEC ,
. regs = {
. override = 0x518 ,
. security = 0x51c ,
} ,
} ,
} ;
static int tegra186_mc_probe ( struct platform_device * pdev )
{
struct resource * res ;
struct tegra_mc * mc ;
unsigned int i ;
int err = 0 ;
mc = devm_kzalloc ( & pdev - > dev , sizeof ( * mc ) , GFP_KERNEL ) ;
if ( ! mc )
return - ENOMEM ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
mc - > regs = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( mc - > regs ) )
return PTR_ERR ( mc - > regs ) ;
mc - > dev = & pdev - > dev ;
for ( i = 0 ; i < ARRAY_SIZE ( tegra186_mc_clients ) ; i + + ) {
const struct tegra_mc_client * client = & tegra186_mc_clients [ i ] ;
u32 override , security ;
override = readl ( mc - > regs + client - > regs . override ) ;
security = readl ( mc - > regs + client - > regs . security ) ;
dev_dbg ( & pdev - > dev , " client %s: override: %x security: %x \n " ,
client - > name , override , security ) ;
dev_dbg ( & pdev - > dev , " setting SID %u for %s \n " , client - > sid ,
client - > name ) ;
writel ( client - > sid , mc - > regs + client - > regs . override ) ;
override = readl ( mc - > regs + client - > regs . override ) ;
security = readl ( mc - > regs + client - > regs . security ) ;
dev_dbg ( & pdev - > dev , " client %s: override: %x security: %x \n " ,
client - > name , override , security ) ;
}
platform_set_drvdata ( pdev , mc ) ;
return err ;
}
static const struct of_device_id tegra186_mc_of_match [ ] = {
{ . compatible = " nvidia,tegra186-mc " , } ,
{ /* sentinel */ }
} ;
MODULE_DEVICE_TABLE ( of , tegra186_mc_of_match ) ;
static struct platform_driver tegra186_mc_driver = {
. driver = {
. name = " tegra186-mc " ,
. of_match_table = tegra186_mc_of_match ,
. suppress_bind_attrs = true ,
} ,
. prevent_deferred_probe = true ,
. probe = tegra186_mc_probe ,
} ;
module_platform_driver ( tegra186_mc_driver ) ;
MODULE_AUTHOR ( " Thierry Reding <treding@nvidia.com> " ) ;
MODULE_DESCRIPTION ( " NVIDIA Tegra186 Memory Controller driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;