2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2016-01-04 20:23:55 +01:00
/*
*
* Copyright ( C ) 2015 Nikolay Martynov < mar . kolya @ gmail . com >
2016-05-05 09:57:56 +02:00
* Copyright ( C ) 2015 John Crispin < john @ phrozen . org >
2016-01-04 20:23:55 +01:00
*/
# include <linux/kernel.h>
# include <linux/init.h>
2020-03-12 12:29:15 +01:00
# include <linux/slab.h>
# include <linux/sys_soc.h>
2021-03-26 22:38:40 -07:00
# include <linux/memblock.h>
2016-01-04 20:23:55 +01:00
2021-03-26 22:38:40 -07:00
# include <asm/bootinfo.h>
2016-01-04 20:23:55 +01:00
# include <asm/mipsregs.h>
# include <asm/smp-ops.h>
2017-08-12 19:49:41 -07:00
# include <asm/mips-cps.h>
2016-01-04 20:23:55 +01:00
# include <asm/mach-ralink/ralink_regs.h>
# include <asm/mach-ralink/mt7621.h>
# include <pinmux.h>
# include "common.h"
# define MT7621_GPIO_MODE_UART1 1
# define MT7621_GPIO_MODE_I2C 2
# define MT7621_GPIO_MODE_UART3_MASK 0x3
# define MT7621_GPIO_MODE_UART3_SHIFT 3
# define MT7621_GPIO_MODE_UART3_GPIO 1
# define MT7621_GPIO_MODE_UART2_MASK 0x3
# define MT7621_GPIO_MODE_UART2_SHIFT 5
# define MT7621_GPIO_MODE_UART2_GPIO 1
# define MT7621_GPIO_MODE_JTAG 7
# define MT7621_GPIO_MODE_WDT_MASK 0x3
# define MT7621_GPIO_MODE_WDT_SHIFT 8
# define MT7621_GPIO_MODE_WDT_GPIO 1
# define MT7621_GPIO_MODE_PCIE_RST 0
# define MT7621_GPIO_MODE_PCIE_REF 2
# define MT7621_GPIO_MODE_PCIE_MASK 0x3
# define MT7621_GPIO_MODE_PCIE_SHIFT 10
# define MT7621_GPIO_MODE_PCIE_GPIO 1
# define MT7621_GPIO_MODE_MDIO_MASK 0x3
# define MT7621_GPIO_MODE_MDIO_SHIFT 12
# define MT7621_GPIO_MODE_MDIO_GPIO 1
# define MT7621_GPIO_MODE_RGMII1 14
# define MT7621_GPIO_MODE_RGMII2 15
# define MT7621_GPIO_MODE_SPI_MASK 0x3
# define MT7621_GPIO_MODE_SPI_SHIFT 16
# define MT7621_GPIO_MODE_SPI_GPIO 1
# define MT7621_GPIO_MODE_SDHCI_MASK 0x3
# define MT7621_GPIO_MODE_SDHCI_SHIFT 18
# define MT7621_GPIO_MODE_SDHCI_GPIO 1
2021-03-26 22:38:40 -07:00
static void * detect_magic __initdata = detect_memory_region ;
2016-01-04 20:23:55 +01:00
static struct rt2880_pmx_func uart1_grp [ ] = { FUNC ( " uart1 " , 0 , 1 , 2 ) } ;
static struct rt2880_pmx_func i2c_grp [ ] = { FUNC ( " i2c " , 0 , 3 , 2 ) } ;
static struct rt2880_pmx_func uart3_grp [ ] = {
FUNC ( " uart3 " , 0 , 5 , 4 ) ,
FUNC ( " i2s " , 2 , 5 , 4 ) ,
FUNC ( " spdif3 " , 3 , 5 , 4 ) ,
} ;
static struct rt2880_pmx_func uart2_grp [ ] = {
FUNC ( " uart2 " , 0 , 9 , 4 ) ,
FUNC ( " pcm " , 2 , 9 , 4 ) ,
FUNC ( " spdif2 " , 3 , 9 , 4 ) ,
} ;
static struct rt2880_pmx_func jtag_grp [ ] = { FUNC ( " jtag " , 0 , 13 , 5 ) } ;
static struct rt2880_pmx_func wdt_grp [ ] = {
FUNC ( " wdt rst " , 0 , 18 , 1 ) ,
FUNC ( " wdt refclk " , 2 , 18 , 1 ) ,
} ;
static struct rt2880_pmx_func pcie_rst_grp [ ] = {
FUNC ( " pcie rst " , MT7621_GPIO_MODE_PCIE_RST , 19 , 1 ) ,
FUNC ( " pcie refclk " , MT7621_GPIO_MODE_PCIE_REF , 19 , 1 )
} ;
static struct rt2880_pmx_func mdio_grp [ ] = { FUNC ( " mdio " , 0 , 20 , 2 ) } ;
static struct rt2880_pmx_func rgmii2_grp [ ] = { FUNC ( " rgmii2 " , 0 , 22 , 12 ) } ;
static struct rt2880_pmx_func spi_grp [ ] = {
FUNC ( " spi " , 0 , 34 , 7 ) ,
FUNC ( " nand1 " , 2 , 34 , 7 ) ,
} ;
static struct rt2880_pmx_func sdhci_grp [ ] = {
FUNC ( " sdhci " , 0 , 41 , 8 ) ,
FUNC ( " nand2 " , 2 , 41 , 8 ) ,
} ;
static struct rt2880_pmx_func rgmii1_grp [ ] = { FUNC ( " rgmii1 " , 0 , 49 , 12 ) } ;
static struct rt2880_pmx_group mt7621_pinmux_data [ ] = {
GRP ( " uart1 " , uart1_grp , 1 , MT7621_GPIO_MODE_UART1 ) ,
GRP ( " i2c " , i2c_grp , 1 , MT7621_GPIO_MODE_I2C ) ,
GRP_G ( " uart3 " , uart3_grp , MT7621_GPIO_MODE_UART3_MASK ,
MT7621_GPIO_MODE_UART3_GPIO , MT7621_GPIO_MODE_UART3_SHIFT ) ,
GRP_G ( " uart2 " , uart2_grp , MT7621_GPIO_MODE_UART2_MASK ,
MT7621_GPIO_MODE_UART2_GPIO , MT7621_GPIO_MODE_UART2_SHIFT ) ,
GRP ( " jtag " , jtag_grp , 1 , MT7621_GPIO_MODE_JTAG ) ,
GRP_G ( " wdt " , wdt_grp , MT7621_GPIO_MODE_WDT_MASK ,
MT7621_GPIO_MODE_WDT_GPIO , MT7621_GPIO_MODE_WDT_SHIFT ) ,
GRP_G ( " pcie " , pcie_rst_grp , MT7621_GPIO_MODE_PCIE_MASK ,
MT7621_GPIO_MODE_PCIE_GPIO , MT7621_GPIO_MODE_PCIE_SHIFT ) ,
GRP_G ( " mdio " , mdio_grp , MT7621_GPIO_MODE_MDIO_MASK ,
MT7621_GPIO_MODE_MDIO_GPIO , MT7621_GPIO_MODE_MDIO_SHIFT ) ,
GRP ( " rgmii2 " , rgmii2_grp , 1 , MT7621_GPIO_MODE_RGMII2 ) ,
GRP_G ( " spi " , spi_grp , MT7621_GPIO_MODE_SPI_MASK ,
MT7621_GPIO_MODE_SPI_GPIO , MT7621_GPIO_MODE_SPI_SHIFT ) ,
GRP_G ( " sdhci " , sdhci_grp , MT7621_GPIO_MODE_SDHCI_MASK ,
MT7621_GPIO_MODE_SDHCI_GPIO , MT7621_GPIO_MODE_SDHCI_SHIFT ) ,
GRP ( " rgmii1 " , rgmii1_grp , 1 , MT7621_GPIO_MODE_RGMII1 ) ,
{ 0 }
} ;
phys_addr_t mips_cpc_default_phys_base ( void )
{
panic ( " Cannot detect cpc address " ) ;
}
2021-03-26 22:38:40 -07:00
static void __init mt7621_memory_detect ( void )
{
void * dm = & detect_magic ;
phys_addr_t size ;
for ( size = 32 * SZ_1M ; size < 256 * SZ_1M ; size < < = 1 ) {
if ( ! __builtin_memcmp ( dm , dm + size , sizeof ( detect_magic ) ) )
break ;
}
if ( ( size = = 256 * SZ_1M ) & &
( CPHYSADDR ( dm + size ) < MT7621_LOWMEM_MAX_SIZE ) & &
__builtin_memcmp ( dm , dm + size , sizeof ( detect_magic ) ) ) {
memblock_add ( MT7621_LOWMEM_BASE , MT7621_LOWMEM_MAX_SIZE ) ;
memblock_add ( MT7621_HIGHMEM_BASE , MT7621_HIGHMEM_SIZE ) ;
} else {
memblock_add ( MT7621_LOWMEM_BASE , size ) ;
}
}
2016-01-04 20:23:55 +01:00
void __init ralink_of_remap ( void )
{
2021-04-10 07:50:58 +02:00
rt_sysc_membase = plat_of_remap_node ( " mediatek,mt7621-sysc " ) ;
rt_memc_membase = plat_of_remap_node ( " mediatek,mt7621-memc " ) ;
2016-01-04 20:23:55 +01:00
if ( ! rt_sysc_membase | | ! rt_memc_membase )
panic ( " Failed to remap core resources " ) ;
}
2020-03-12 12:29:15 +01:00
static void soc_dev_init ( struct ralink_soc_info * soc_info , u32 rev )
{
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 )
return ;
soc_dev_attr - > soc_id = " mt7621 " ;
soc_dev_attr - > family = " Ralink " ;
if ( ( ( rev > > CHIP_REV_VER_SHIFT ) & CHIP_REV_VER_MASK ) = = 1 & &
( rev & CHIP_REV_ECO_MASK ) = = 1 )
soc_dev_attr - > revision = " E2 " ;
else
soc_dev_attr - > revision = " E1 " ;
soc_dev_attr - > data = soc_info ;
soc_dev = soc_device_register ( soc_dev_attr ) ;
if ( IS_ERR ( soc_dev ) ) {
kfree ( soc_dev_attr ) ;
return ;
}
}
2021-03-26 22:38:39 -07:00
void __init prom_soc_init ( struct ralink_soc_info * soc_info )
2016-01-04 20:23:55 +01:00
{
void __iomem * sysc = ( void __iomem * ) KSEG1ADDR ( MT7621_SYSC_BASE ) ;
unsigned char * name = NULL ;
u32 n0 ;
u32 n1 ;
u32 rev ;
2018-03-21 14:02:10 +11: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 ( ) ;
}
2016-01-04 20:23:55 +01:00
n0 = __raw_readl ( sysc + SYSC_REG_CHIP_NAME0 ) ;
n1 = __raw_readl ( sysc + SYSC_REG_CHIP_NAME1 ) ;
if ( n0 = = MT7621_CHIP_NAME0 & & n1 = = MT7621_CHIP_NAME1 ) {
name = " MT7621 " ;
2021-04-10 07:50:58 +02:00
soc_info - > compatible = " mediatek,mt7621-soc " ;
2016-01-04 20:23:55 +01:00
} else {
panic ( " mt7621: unknown SoC, n0:%08x n1:%08x \n " , n0 , n1 ) ;
}
2016-12-20 19:12:40 +01:00
ralink_soc = MT762X_SOC_MT7621AT ;
2016-01-04 20:23:55 +01:00
rev = __raw_readl ( sysc + SYSC_REG_CHIP_REV ) ;
snprintf ( soc_info - > sys_type , RAMIPS_SYS_TYPE_LEN ,
" MediaTek %s ver:%u eco:%u " ,
name ,
( rev > > CHIP_REV_VER_SHIFT ) & CHIP_REV_VER_MASK ,
( rev & CHIP_REV_ECO_MASK ) ) ;
2021-03-26 22:38:40 -07:00
soc_info - > mem_detect = mt7621_memory_detect ;
2016-01-04 20:23:55 +01:00
rt2880_pinmux_data = mt7621_pinmux_data ;
2020-03-28 11:27:13 +01:00
soc_dev_init ( soc_info , rev ) ;
2016-01-04 20:23:55 +01:00
if ( ! register_cps_smp_ops ( ) )
return ;
if ( ! register_cmp_smp_ops ( ) )
return ;
if ( ! register_vsmp_smp_ops ( ) )
return ;
}