2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2016-01-04 22:23:55 +03:00
/*
*
* Copyright ( C ) 2015 Nikolay Martynov < mar . kolya @ gmail . com >
2016-05-05 10:57:56 +03:00
* Copyright ( C ) 2015 John Crispin < john @ phrozen . org >
2016-01-04 22:23:55 +03:00
*/
# include <linux/kernel.h>
# include <linux/init.h>
2020-03-12 14:29:15 +03:00
# include <linux/slab.h>
# include <linux/sys_soc.h>
2021-03-27 08:38:40 +03:00
# include <linux/memblock.h>
2021-12-07 13:49:21 +03:00
# include <linux/pci.h>
# include <linux/bug.h>
2016-01-04 22:23:55 +03:00
2021-03-27 08:38:40 +03:00
# include <asm/bootinfo.h>
2016-01-04 22:23:55 +03:00
# include <asm/mipsregs.h>
# include <asm/smp-ops.h>
2017-08-13 05:49:41 +03:00
# include <asm/mips-cps.h>
2016-01-04 22:23:55 +03:00
# include <asm/mach-ralink/ralink_regs.h>
# include <asm/mach-ralink/mt7621.h>
# include "common.h"
2022-02-11 03:13:44 +03:00
# define MT7621_MEM_TEST_PATTERN 0xaa5555aa
static u32 detect_magic __initdata ;
2022-11-14 04:56:58 +03:00
static struct ralink_soc_info * soc_info_ptr ;
2021-03-27 08:38:40 +03:00
2021-12-07 13:49:21 +03:00
int pcibios_root_bridge_prepare ( struct pci_host_bridge * bridge )
{
struct resource_entry * entry ;
resource_size_t mask ;
entry = resource_list_first_type ( & bridge - > windows , IORESOURCE_MEM ) ;
if ( ! entry ) {
pr_err ( " Cannot get memory resource \n " ) ;
return - EINVAL ;
}
if ( mips_cps_numiocu ( 0 ) ) {
/*
* Hardware doesn ' t accept mask values with 1 s after
* 0 s ( e . g . 0xffef ) , so warn if that ' s happen
*/
mask = ~ ( entry - > res - > end - entry - > res - > start ) & CM_GCR_REGn_MASK_ADDRMASK ;
WARN_ON ( mask & & BIT ( ffz ( ~ mask ) ) - 1 ! = ~ mask ) ;
write_gcr_reg1_base ( entry - > res - > start ) ;
write_gcr_reg1_mask ( mask | CM_GCR_REGn_MASK_CMTGT_IOCU0 ) ;
pr_info ( " PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx \n " ,
( unsigned long long ) read_gcr_reg1_base ( ) ,
( unsigned long long ) read_gcr_reg1_mask ( ) ) ;
}
return 0 ;
}
2016-01-04 22:23:55 +03:00
phys_addr_t mips_cpc_default_phys_base ( void )
{
panic ( " Cannot detect cpc address " ) ;
}
2022-02-11 03:13:44 +03:00
static bool __init mt7621_addr_wraparound_test ( phys_addr_t size )
{
void * dm = ( void * ) KSEG1ADDR ( & detect_magic ) ;
if ( CPHYSADDR ( dm + size ) > = MT7621_LOWMEM_MAX_SIZE )
return true ;
__raw_writel ( MT7621_MEM_TEST_PATTERN , dm ) ;
if ( __raw_readl ( dm ) ! = __raw_readl ( dm + size ) )
return false ;
2022-03-01 04:15:07 +03:00
__raw_writel ( ~ MT7621_MEM_TEST_PATTERN , dm ) ;
2022-02-11 03:13:44 +03:00
return __raw_readl ( dm ) = = __raw_readl ( dm + size ) ;
}
2021-03-27 08:38:40 +03:00
static void __init mt7621_memory_detect ( void )
{
phys_addr_t size ;
2022-02-11 03:13:44 +03:00
for ( size = 32 * SZ_1M ; size < = 256 * SZ_1M ; size < < = 1 ) {
if ( mt7621_addr_wraparound_test ( size ) ) {
memblock_add ( MT7621_LOWMEM_BASE , size ) ;
return ;
}
2021-03-27 08:38:40 +03:00
}
2022-02-11 03:13:44 +03:00
memblock_add ( MT7621_LOWMEM_BASE , MT7621_LOWMEM_MAX_SIZE ) ;
memblock_add ( MT7621_HIGHMEM_BASE , MT7621_HIGHMEM_SIZE ) ;
2021-03-27 08:38:40 +03:00
}
2022-11-14 04:56:57 +03:00
static unsigned int __init mt7621_get_soc_name0 ( void )
{
return __raw_readl ( MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0 ) ;
}
static unsigned int __init mt7621_get_soc_name1 ( void )
{
return __raw_readl ( MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME1 ) ;
}
static bool __init mt7621_soc_valid ( void )
{
if ( mt7621_get_soc_name0 ( ) = = MT7621_CHIP_NAME0 & &
mt7621_get_soc_name1 ( ) = = MT7621_CHIP_NAME1 )
return true ;
else
return false ;
}
static const char __init * mt7621_get_soc_id ( void )
{
if ( mt7621_soc_valid ( ) )
return " MT7621 " ;
else
return " invalid " ;
}
static unsigned int __init mt7621_get_soc_rev ( void )
{
return __raw_readl ( MT7621_SYSC_BASE + SYSC_REG_CHIP_REV ) ;
}
static unsigned int __init mt7621_get_soc_ver ( void )
{
return ( mt7621_get_soc_rev ( ) > > CHIP_REV_VER_SHIFT ) & CHIP_REV_VER_MASK ;
}
static unsigned int __init mt7621_get_soc_eco ( void )
{
return ( mt7621_get_soc_rev ( ) & CHIP_REV_ECO_MASK ) ;
}
static const char __init * mt7621_get_soc_revision ( void )
{
if ( mt7621_get_soc_rev ( ) = = 1 & & mt7621_get_soc_eco ( ) = = 1 )
return " E2 " ;
else
return " E1 " ;
}
2022-11-14 04:56:58 +03:00
static int __init mt7621_soc_dev_init ( void )
2020-03-12 14:29:15 +03:00
{
struct soc_device * soc_dev ;
struct soc_device_attribute * soc_dev_attr ;
soc_dev_attr = kzalloc ( sizeof ( * soc_dev_attr ) , GFP_KERNEL ) ;
if ( ! soc_dev_attr )
2022-11-14 04:56:58 +03:00
return - ENOMEM ;
2020-03-12 14:29:15 +03:00
soc_dev_attr - > soc_id = " mt7621 " ;
soc_dev_attr - > family = " Ralink " ;
2022-11-14 04:56:57 +03:00
soc_dev_attr - > revision = mt7621_get_soc_revision ( ) ;
2020-03-12 14:29:15 +03:00
2022-11-14 04:56:58 +03:00
soc_dev_attr - > data = soc_info_ptr ;
2020-03-12 14:29:15 +03:00
soc_dev = soc_device_register ( soc_dev_attr ) ;
if ( IS_ERR ( soc_dev ) ) {
kfree ( soc_dev_attr ) ;
2022-11-14 04:56:58 +03:00
return PTR_ERR ( soc_dev ) ;
2020-03-12 14:29:15 +03:00
}
2022-11-14 04:56:58 +03:00
return 0 ;
2020-03-12 14:29:15 +03:00
}
2022-11-14 04:56:58 +03:00
device_initcall ( mt7621_soc_dev_init ) ;
2020-03-12 14:29:15 +03:00
2021-03-27 08:38:39 +03:00
void __init prom_soc_init ( struct ralink_soc_info * soc_info )
2016-01-04 22:23:55 +03:00
{
2018-03-21 06:02:10 +03:00
/* Early detection of CMP support */
mips_cm_probe ( ) ;
mips_cpc_probe ( ) ;
if ( mips_cps_numiocu ( 0 ) ) {
/*
* mips_cm_probe ( ) wipes out bootloader
* config for CM regions and we have to configure them
* again . This SoC cannot talk to pamlbus devices
* witout proper iocu region set up .
*
* FIXME : it would be better to do this with values
* from DT , but we need this very early because
* without this we cannot talk to pretty much anything
* including serial .
*/
write_gcr_reg0_base ( MT7621_PALMBUS_BASE ) ;
write_gcr_reg0_mask ( ~ MT7621_PALMBUS_SIZE |
CM_GCR_REGn_MASK_CMTGT_IOCU0 ) ;
__sync ( ) ;
}
2022-11-14 04:56:57 +03:00
if ( mt7621_soc_valid ( ) )
2021-04-10 08:50:58 +03:00
soc_info - > compatible = " mediatek,mt7621-soc " ;
2022-11-14 04:56:57 +03:00
else
panic ( " mt7621: unknown SoC, n0:%08x n1:%08x \n " ,
mt7621_get_soc_name0 ( ) ,
mt7621_get_soc_name1 ( ) ) ;
2016-12-20 21:12:40 +03:00
ralink_soc = MT762X_SOC_MT7621AT ;
2016-01-04 22:23:55 +03:00
snprintf ( soc_info - > sys_type , RAMIPS_SYS_TYPE_LEN ,
" MediaTek %s ver:%u eco:%u " ,
2022-11-14 04:56:57 +03:00
mt7621_get_soc_id ( ) ,
mt7621_get_soc_ver ( ) ,
mt7621_get_soc_eco ( ) ) ;
2016-01-04 22:23:55 +03:00
2021-03-27 08:38:40 +03:00
soc_info - > mem_detect = mt7621_memory_detect ;
2016-01-04 22:23:55 +03:00
2022-11-14 04:56:58 +03:00
soc_info_ptr = soc_info ;
2020-03-28 13:27:13 +03:00
2016-01-04 22:23:55 +03:00
if ( ! register_cps_smp_ops ( ) )
return ;
if ( ! register_vsmp_smp_ops ( ) )
return ;
}