2018-01-26 12:50:27 -06:00
// SPDX-License-Identifier: GPL-2.0
2017-06-19 18:23:48 +08:00
/*
* PCIe host controller driver for Kirin Phone SoCs
*
2019-05-30 08:05:58 -05:00
* Copyright ( C ) 2017 HiSilicon Electronics Co . , Ltd .
2020-06-27 12:30:50 +02:00
* https : //www.huawei.com
2017-06-19 18:23:48 +08:00
*
* Author : Xiaowei Song < songxiaowei @ huawei . com >
*/
# include <linux/clk.h>
2021-10-21 11:45:09 +01:00
# include <linux/compiler.h>
2017-06-19 18:23:48 +08:00
# include <linux/delay.h>
# include <linux/err.h>
2022-08-30 21:33:10 +03:00
# include <linux/gpio/consumer.h>
2017-06-19 18:23:48 +08:00
# include <linux/interrupt.h>
# include <linux/mfd/syscon.h>
2023-07-14 11:48:25 -06:00
# include <linux/of.h>
2017-06-19 18:23:48 +08:00
# include <linux/of_pci.h>
2021-10-21 11:45:09 +01:00
# include <linux/phy/phy.h>
2017-06-19 18:23:48 +08:00
# include <linux/pci.h>
# include <linux/pci_regs.h>
# include <linux/platform_device.h>
# include <linux/regmap.h>
# include <linux/resource.h>
# include <linux/types.h>
# include "pcie-designware.h"
# define to_kirin_pcie(x) dev_get_drvdata((x)->dev)
/* PCIe ELBI registers */
# define SOC_PCIECTRL_CTRL0_ADDR 0x000
# define SOC_PCIECTRL_CTRL1_ADDR 0x004
# define PCIE_ELBI_SLV_DBI_ENABLE (0x1 << 21)
/* info located in APB */
# define PCIE_APP_LTSSM_ENABLE 0x01c
# define PCIE_APB_PHY_STATUS0 0x400
# define PCIE_LINKUP_ENABLE (0x8020)
# define PCIE_LTSSM_ENABLE_BIT (0x1 << 11)
/* info located in sysctrl */
# define SCTRL_PCIE_CMOS_OFFSET 0x60
# define SCTRL_PCIE_CMOS_BIT 0x10
# define SCTRL_PCIE_ISO_OFFSET 0x44
# define SCTRL_PCIE_ISO_BIT 0x30
# define SCTRL_PCIE_HPCLK_OFFSET 0x190
# define SCTRL_PCIE_HPCLK_BIT 0x184000
# define SCTRL_PCIE_OE_OFFSET 0x14a
# define PCIE_DEBOUNCE_PARAM 0xF0F400
# define PCIE_OE_BYPASS (0x3 << 28)
2021-10-21 11:45:11 +01:00
/*
* Max number of connected PCI slots at an external PCI bridge
*
* This is used on HiKey 970 , which has a PEX 8606 bridge with 4 connected
* lanes ( lane 0 upstream , and the other three lanes , one connected to an
* in - board Ethernet adapter and the other two connected to M .2 and mini
* PCI slots .
*
* Each slot has a different clock source and uses a separate PERST # pin .
*/
# define MAX_PCI_SLOTS 3
2021-10-21 11:45:09 +01:00
enum pcie_kirin_phy_type {
PCIE_KIRIN_INTERNAL_PHY ,
PCIE_KIRIN_EXTERNAL_PHY
} ;
2021-10-21 11:45:08 +01:00
struct kirin_pcie {
2021-10-21 11:45:09 +01:00
enum pcie_kirin_phy_type type ;
2021-10-21 11:45:08 +01:00
struct dw_pcie * pci ;
2021-10-21 11:45:10 +01:00
struct regmap * apb ;
2021-10-21 11:45:08 +01:00
struct phy * phy ;
2021-10-21 11:45:09 +01:00
void * phy_priv ; /* only for PCIE_KIRIN_INTERNAL_PHY */
2021-10-21 11:45:11 +01:00
/* DWC PERST# */
2024-05-06 17:20:41 +03:00
struct gpio_desc * id_dwc_perst_gpio ;
2021-10-21 11:45:11 +01:00
/* Per-slot PERST# */
int num_slots ;
2024-05-06 17:20:41 +03:00
struct gpio_desc * id_reset_gpio [ MAX_PCI_SLOTS ] ;
2021-10-21 11:45:11 +01:00
const char * reset_names [ MAX_PCI_SLOTS ] ;
/* Per-slot clkreq */
int n_gpio_clkreq ;
2024-05-06 17:20:41 +03:00
struct gpio_desc * id_clkreq_gpio [ MAX_PCI_SLOTS ] ;
2021-10-21 11:45:11 +01:00
const char * clkreq_names [ MAX_PCI_SLOTS ] ;
2021-10-21 11:45:08 +01:00
} ;
/*
* Kirin 960 PHY . Can ' t be split into a PHY driver without changing the
* DT schema .
*/
# define REF_CLK_FREQ 100000000
/* PHY info located in APB */
# define PCIE_APB_PHY_CTRL0 0x0
# define PCIE_APB_PHY_CTRL1 0x4
# define PCIE_APB_PHY_STATUS0 0x400
# define PIPE_CLK_STABLE BIT(19)
# define PHY_REF_PAD_BIT BIT(8)
# define PHY_PWR_DOWN_BIT BIT(22)
# define PHY_RST_ACK_BIT BIT(16)
2017-06-19 18:23:48 +08:00
/* peri_crg ctrl */
# define CRGCTRL_PCIE_ASSERT_OFFSET 0x88
# define CRGCTRL_PCIE_ASSERT_BIT 0x8c000000
/* Time for delay */
2021-10-21 11:45:11 +01:00
# define REF_2_PERST_MIN 21000
2017-06-19 18:23:48 +08:00
# define REF_2_PERST_MAX 25000
# define PERST_2_ACCESS_MIN 10000
# define PERST_2_ACCESS_MAX 12000
# define PIPE_CLK_WAIT_MIN 550
# define PIPE_CLK_WAIT_MAX 600
# define TIME_CMOS_MIN 100
# define TIME_CMOS_MAX 105
# define TIME_PHY_PD_MIN 10
# define TIME_PHY_PD_MAX 11
2021-10-21 11:45:08 +01:00
struct hi3660_pcie_phy {
struct device * dev ;
void __iomem * base ;
2017-06-19 18:23:48 +08:00
struct regmap * crgctrl ;
struct regmap * sysctrl ;
struct clk * apb_sys_clk ;
struct clk * apb_phy_clk ;
struct clk * phy_ref_clk ;
2021-10-21 11:45:08 +01:00
struct clk * aclk ;
struct clk * aux_clk ;
2017-06-19 18:23:48 +08:00
} ;
/* Registers in PCIePHY */
2021-10-21 11:45:08 +01:00
static inline void kirin_apb_phy_writel ( struct hi3660_pcie_phy * hi3660_pcie_phy ,
2017-06-19 18:23:48 +08:00
u32 val , u32 reg )
{
2021-10-21 11:45:08 +01:00
writel ( val , hi3660_pcie_phy - > base + reg ) ;
2017-06-19 18:23:48 +08:00
}
2021-10-21 11:45:08 +01:00
static inline u32 kirin_apb_phy_readl ( struct hi3660_pcie_phy * hi3660_pcie_phy ,
u32 reg )
2017-06-19 18:23:48 +08:00
{
2021-10-21 11:45:08 +01:00
return readl ( hi3660_pcie_phy - > base + reg ) ;
2017-06-19 18:23:48 +08:00
}
2021-10-21 11:45:08 +01:00
static int hi3660_pcie_phy_get_clk ( struct hi3660_pcie_phy * phy )
2017-06-19 18:23:48 +08:00
{
2021-10-21 11:45:08 +01:00
struct device * dev = phy - > dev ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
phy - > phy_ref_clk = devm_clk_get ( dev , " pcie_phy_ref " ) ;
if ( IS_ERR ( phy - > phy_ref_clk ) )
return PTR_ERR ( phy - > phy_ref_clk ) ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
phy - > aux_clk = devm_clk_get ( dev , " pcie_aux " ) ;
if ( IS_ERR ( phy - > aux_clk ) )
return PTR_ERR ( phy - > aux_clk ) ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
phy - > apb_phy_clk = devm_clk_get ( dev , " pcie_apb_phy " ) ;
if ( IS_ERR ( phy - > apb_phy_clk ) )
return PTR_ERR ( phy - > apb_phy_clk ) ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
phy - > apb_sys_clk = devm_clk_get ( dev , " pcie_apb_sys " ) ;
if ( IS_ERR ( phy - > apb_sys_clk ) )
return PTR_ERR ( phy - > apb_sys_clk ) ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
phy - > aclk = devm_clk_get ( dev , " pcie_aclk " ) ;
if ( IS_ERR ( phy - > aclk ) )
return PTR_ERR ( phy - > aclk ) ;
2017-06-19 18:23:48 +08:00
return 0 ;
}
2021-10-21 11:45:08 +01:00
static int hi3660_pcie_phy_get_resource ( struct hi3660_pcie_phy * phy )
2017-06-19 18:23:48 +08:00
{
2021-10-21 11:45:08 +01:00
struct device * dev = phy - > dev ;
struct platform_device * pdev ;
/* registers */
pdev = container_of ( dev , struct platform_device , dev ) ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
phy - > base = devm_platform_ioremap_resource_byname ( pdev , " phy " ) ;
if ( IS_ERR ( phy - > base ) )
return PTR_ERR ( phy - > base ) ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
phy - > crgctrl = syscon_regmap_lookup_by_compatible ( " hisilicon,hi3660-crgctrl " ) ;
if ( IS_ERR ( phy - > crgctrl ) )
return PTR_ERR ( phy - > crgctrl ) ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
phy - > sysctrl = syscon_regmap_lookup_by_compatible ( " hisilicon,hi3660-sctrl " ) ;
if ( IS_ERR ( phy - > sysctrl ) )
return PTR_ERR ( phy - > sysctrl ) ;
2017-06-19 18:23:48 +08:00
return 0 ;
}
2021-10-21 11:45:08 +01:00
static int hi3660_pcie_phy_start ( struct hi3660_pcie_phy * phy )
2017-06-19 18:23:48 +08:00
{
2021-10-21 11:45:08 +01:00
struct device * dev = phy - > dev ;
2017-06-19 18:23:48 +08:00
u32 reg_val ;
2021-10-21 11:45:08 +01:00
reg_val = kirin_apb_phy_readl ( phy , PCIE_APB_PHY_CTRL1 ) ;
2017-06-19 18:23:48 +08:00
reg_val & = ~ PHY_REF_PAD_BIT ;
2021-10-21 11:45:08 +01:00
kirin_apb_phy_writel ( phy , reg_val , PCIE_APB_PHY_CTRL1 ) ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
reg_val = kirin_apb_phy_readl ( phy , PCIE_APB_PHY_CTRL0 ) ;
2017-06-19 18:23:48 +08:00
reg_val & = ~ PHY_PWR_DOWN_BIT ;
2021-10-21 11:45:08 +01:00
kirin_apb_phy_writel ( phy , reg_val , PCIE_APB_PHY_CTRL0 ) ;
2017-06-19 18:23:48 +08:00
usleep_range ( TIME_PHY_PD_MIN , TIME_PHY_PD_MAX ) ;
2021-10-21 11:45:08 +01:00
reg_val = kirin_apb_phy_readl ( phy , PCIE_APB_PHY_CTRL1 ) ;
2017-06-19 18:23:48 +08:00
reg_val & = ~ PHY_RST_ACK_BIT ;
2021-10-21 11:45:08 +01:00
kirin_apb_phy_writel ( phy , reg_val , PCIE_APB_PHY_CTRL1 ) ;
2017-06-19 18:23:48 +08:00
usleep_range ( PIPE_CLK_WAIT_MIN , PIPE_CLK_WAIT_MAX ) ;
2021-10-21 11:45:08 +01:00
reg_val = kirin_apb_phy_readl ( phy , PCIE_APB_PHY_STATUS0 ) ;
2017-06-19 18:23:48 +08:00
if ( reg_val & PIPE_CLK_STABLE ) {
dev_err ( dev , " PIPE clk is not stable \n " ) ;
return - EINVAL ;
}
return 0 ;
}
2021-10-21 11:45:08 +01:00
static void hi3660_pcie_phy_oe_enable ( struct hi3660_pcie_phy * phy )
2017-06-19 18:23:48 +08:00
{
u32 val ;
2021-10-21 11:45:08 +01:00
regmap_read ( phy - > sysctrl , SCTRL_PCIE_OE_OFFSET , & val ) ;
2017-06-19 18:23:48 +08:00
val | = PCIE_DEBOUNCE_PARAM ;
val & = ~ PCIE_OE_BYPASS ;
2021-10-21 11:45:08 +01:00
regmap_write ( phy - > sysctrl , SCTRL_PCIE_OE_OFFSET , val ) ;
2017-06-19 18:23:48 +08:00
}
2021-10-21 11:45:08 +01:00
static int hi3660_pcie_phy_clk_ctrl ( struct hi3660_pcie_phy * phy , bool enable )
2017-06-19 18:23:48 +08:00
{
int ret = 0 ;
if ( ! enable )
goto close_clk ;
2021-10-21 11:45:08 +01:00
ret = clk_set_rate ( phy - > phy_ref_clk , REF_CLK_FREQ ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
return ret ;
2021-10-21 11:45:08 +01:00
ret = clk_prepare_enable ( phy - > phy_ref_clk ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
return ret ;
2021-10-21 11:45:08 +01:00
ret = clk_prepare_enable ( phy - > apb_sys_clk ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
goto apb_sys_fail ;
2021-10-21 11:45:08 +01:00
ret = clk_prepare_enable ( phy - > apb_phy_clk ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
goto apb_phy_fail ;
2021-10-21 11:45:08 +01:00
ret = clk_prepare_enable ( phy - > aclk ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
goto aclk_fail ;
2021-10-21 11:45:08 +01:00
ret = clk_prepare_enable ( phy - > aux_clk ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
goto aux_clk_fail ;
return 0 ;
close_clk :
2021-10-21 11:45:08 +01:00
clk_disable_unprepare ( phy - > aux_clk ) ;
2017-06-19 18:23:48 +08:00
aux_clk_fail :
2021-10-21 11:45:08 +01:00
clk_disable_unprepare ( phy - > aclk ) ;
2017-06-19 18:23:48 +08:00
aclk_fail :
2021-10-21 11:45:08 +01:00
clk_disable_unprepare ( phy - > apb_phy_clk ) ;
2017-06-19 18:23:48 +08:00
apb_phy_fail :
2021-10-21 11:45:08 +01:00
clk_disable_unprepare ( phy - > apb_sys_clk ) ;
2017-06-19 18:23:48 +08:00
apb_sys_fail :
2021-10-21 11:45:08 +01:00
clk_disable_unprepare ( phy - > phy_ref_clk ) ;
2017-06-19 18:23:48 +08:00
return ret ;
}
2021-10-21 11:45:08 +01:00
static int hi3660_pcie_phy_power_on ( struct kirin_pcie * pcie )
2017-06-19 18:23:48 +08:00
{
2021-10-21 11:45:08 +01:00
struct hi3660_pcie_phy * phy = pcie - > phy_priv ;
2017-06-19 18:23:48 +08:00
int ret ;
/* Power supply for Host */
2021-10-21 11:45:08 +01:00
regmap_write ( phy - > sysctrl ,
2017-06-19 18:23:48 +08:00
SCTRL_PCIE_CMOS_OFFSET , SCTRL_PCIE_CMOS_BIT ) ;
usleep_range ( TIME_CMOS_MIN , TIME_CMOS_MAX ) ;
2021-10-21 11:45:08 +01:00
hi3660_pcie_phy_oe_enable ( phy ) ;
ret = hi3660_pcie_phy_clk_ctrl ( phy , true ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
return ret ;
/* ISO disable, PCIeCtrl, PHY assert and clk gate clear */
2021-10-21 11:45:08 +01:00
regmap_write ( phy - > sysctrl ,
2017-06-19 18:23:48 +08:00
SCTRL_PCIE_ISO_OFFSET , SCTRL_PCIE_ISO_BIT ) ;
2021-10-21 11:45:08 +01:00
regmap_write ( phy - > crgctrl ,
2017-06-19 18:23:48 +08:00
CRGCTRL_PCIE_ASSERT_OFFSET , CRGCTRL_PCIE_ASSERT_BIT ) ;
2021-10-21 11:45:08 +01:00
regmap_write ( phy - > sysctrl ,
2017-06-19 18:23:48 +08:00
SCTRL_PCIE_HPCLK_OFFSET , SCTRL_PCIE_HPCLK_BIT ) ;
2021-10-21 11:45:08 +01:00
ret = hi3660_pcie_phy_start ( phy ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
2021-10-21 11:45:08 +01:00
goto disable_clks ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:11 +01:00
return 0 ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:08 +01:00
disable_clks :
hi3660_pcie_phy_clk_ctrl ( phy , false ) ;
2017-06-19 18:23:48 +08:00
return ret ;
}
2021-10-21 11:45:08 +01:00
static int hi3660_pcie_phy_init ( struct platform_device * pdev ,
struct kirin_pcie * pcie )
{
struct device * dev = & pdev - > dev ;
struct hi3660_pcie_phy * phy ;
int ret ;
phy = devm_kzalloc ( dev , sizeof ( * phy ) , GFP_KERNEL ) ;
if ( ! phy )
return - ENOMEM ;
pcie - > phy_priv = phy ;
phy - > dev = dev ;
ret = hi3660_pcie_phy_get_clk ( phy ) ;
if ( ret )
return ret ;
return hi3660_pcie_phy_get_resource ( phy ) ;
}
2021-10-21 11:45:16 +01:00
static int hi3660_pcie_phy_power_off ( struct kirin_pcie * pcie )
{
struct hi3660_pcie_phy * phy = pcie - > phy_priv ;
/* Drop power supply for Host */
regmap_write ( phy - > sysctrl , SCTRL_PCIE_CMOS_OFFSET , 0x00 ) ;
hi3660_pcie_phy_clk_ctrl ( phy , false ) ;
return 0 ;
}
2021-10-21 11:45:08 +01:00
/*
* The non - PHY part starts here
*/
2021-10-21 11:45:10 +01:00
static const struct regmap_config pcie_kirin_regmap_conf = {
. name = " kirin_pcie_apb " ,
. reg_bits = 32 ,
. val_bits = 32 ,
. reg_stride = 4 ,
} ;
2021-10-21 11:45:08 +01:00
2021-10-21 11:45:11 +01:00
static int kirin_pcie_get_gpio_enable ( struct kirin_pcie * pcie ,
struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
int ret , i ;
/* This is an optional property */
2022-08-30 21:33:10 +03:00
ret = gpiod_count ( dev , " hisilicon,clken " ) ;
2021-10-21 11:45:11 +01:00
if ( ret < 0 )
return 0 ;
if ( ret > MAX_PCI_SLOTS ) {
dev_err ( dev , " Too many GPIO clock requests! \n " ) ;
return - EINVAL ;
}
pcie - > n_gpio_clkreq = ret ;
for ( i = 0 ; i < pcie - > n_gpio_clkreq ; i + + ) {
2024-05-06 17:20:41 +03:00
pcie - > id_clkreq_gpio [ i ] = devm_gpiod_get_index ( dev ,
" hisilicon,clken " , i ,
GPIOD_OUT_LOW ) ;
if ( IS_ERR ( pcie - > id_clkreq_gpio [ i ] ) )
return dev_err_probe ( dev , PTR_ERR ( pcie - > id_clkreq_gpio [ i ] ) ,
" unable to get a valid clken gpio \n " ) ;
2021-10-21 11:45:11 +01:00
2023-11-18 08:55:48 +01:00
pcie - > clkreq_names [ i ] = devm_kasprintf ( dev , GFP_KERNEL ,
" pcie_clkreq_%d " , i ) ;
2021-10-21 11:45:11 +01:00
if ( ! pcie - > clkreq_names [ i ] )
return - ENOMEM ;
2024-05-06 17:20:41 +03:00
gpiod_set_consumer_name ( pcie - > id_clkreq_gpio [ i ] ,
pcie - > clkreq_names [ i ] ) ;
2021-10-21 11:45:11 +01:00
}
return 0 ;
}
static int kirin_pcie_parse_port ( struct kirin_pcie * pcie ,
struct platform_device * pdev ,
struct device_node * node )
{
struct device * dev = & pdev - > dev ;
int ret , slot , i ;
2024-06-09 12:56:14 +02:00
for_each_available_child_of_node_scoped ( node , parent ) {
for_each_available_child_of_node_scoped ( parent , child ) {
2021-10-21 11:45:11 +01:00
i = pcie - > num_slots ;
2024-05-06 17:20:41 +03:00
pcie - > id_reset_gpio [ i ] = devm_fwnode_gpiod_get_index ( dev ,
of_fwnode_handle ( child ) ,
" reset " , 0 , GPIOD_OUT_LOW ,
NULL ) ;
if ( IS_ERR ( pcie - > id_reset_gpio [ i ] ) ) {
if ( PTR_ERR ( pcie - > id_reset_gpio [ i ] ) = = - ENOENT )
continue ;
return dev_err_probe ( dev , PTR_ERR ( pcie - > id_reset_gpio [ i ] ) ,
" unable to get a valid reset gpio \n " ) ;
}
2021-10-21 11:45:11 +01:00
pcie - > num_slots + + ;
if ( pcie - > num_slots > MAX_PCI_SLOTS ) {
dev_err ( dev , " Too many PCI slots! \n " ) ;
2024-06-09 12:56:14 +02:00
return - EINVAL ;
2021-10-21 11:45:11 +01:00
}
ret = of_pci_get_devfn ( child ) ;
if ( ret < 0 ) {
dev_err ( dev , " failed to parse devfn: %d \n " , ret ) ;
2024-06-09 12:56:14 +02:00
return ret ;
2021-10-21 11:45:11 +01:00
}
slot = PCI_SLOT ( ret ) ;
2023-11-18 08:55:48 +01:00
pcie - > reset_names [ i ] = devm_kasprintf ( dev , GFP_KERNEL ,
" pcie_perst_%d " ,
slot ) ;
2024-06-09 12:56:14 +02:00
if ( ! pcie - > reset_names [ i ] )
return - ENOMEM ;
2024-05-06 17:20:41 +03:00
gpiod_set_consumer_name ( pcie - > id_reset_gpio [ i ] ,
pcie - > reset_names [ i ] ) ;
2021-10-21 11:45:11 +01:00
}
}
return 0 ;
}
2021-10-21 11:45:08 +01:00
static long kirin_pcie_get_resource ( struct kirin_pcie * kirin_pcie ,
struct platform_device * pdev )
{
2021-10-21 11:45:10 +01:00
struct device * dev = & pdev - > dev ;
2021-10-21 11:45:11 +01:00
struct device_node * child , * node = dev - > of_node ;
2021-10-21 11:45:10 +01:00
void __iomem * apb_base ;
2021-10-21 11:45:11 +01:00
int ret ;
2021-10-21 11:45:10 +01:00
apb_base = devm_platform_ioremap_resource_byname ( pdev , " apb " ) ;
if ( IS_ERR ( apb_base ) )
return PTR_ERR ( apb_base ) ;
kirin_pcie - > apb = devm_regmap_init_mmio ( dev , apb_base ,
& pcie_kirin_regmap_conf ) ;
if ( IS_ERR ( kirin_pcie - > apb ) )
return PTR_ERR ( kirin_pcie - > apb ) ;
2021-10-21 11:45:08 +01:00
2021-10-21 11:45:11 +01:00
/* pcie internal PERST# gpio */
2024-05-06 17:20:41 +03:00
kirin_pcie - > id_dwc_perst_gpio = devm_gpiod_get ( dev , " reset " , GPIOD_OUT_LOW ) ;
if ( IS_ERR ( kirin_pcie - > id_dwc_perst_gpio ) )
return dev_err_probe ( dev , PTR_ERR ( kirin_pcie - > id_dwc_perst_gpio ) ,
" unable to get a valid gpio pin \n " ) ;
gpiod_set_consumer_name ( kirin_pcie - > id_dwc_perst_gpio , " pcie_perst_bridge " ) ;
2021-10-21 11:45:11 +01:00
ret = kirin_pcie_get_gpio_enable ( kirin_pcie , pdev ) ;
if ( ret )
return ret ;
/* Parse OF children */
for_each_available_child_of_node ( node , child ) {
ret = kirin_pcie_parse_port ( kirin_pcie , pdev , child ) ;
if ( ret )
goto put_node ;
}
2021-10-21 11:45:08 +01:00
return 0 ;
2021-10-21 11:45:11 +01:00
put_node :
of_node_put ( child ) ;
return ret ;
2021-10-21 11:45:08 +01:00
}
2017-06-19 18:23:48 +08:00
static void kirin_pcie_sideband_dbi_w_mode ( struct kirin_pcie * kirin_pcie ,
bool on )
{
u32 val ;
2021-10-21 11:45:10 +01:00
regmap_read ( kirin_pcie - > apb , SOC_PCIECTRL_CTRL0_ADDR , & val ) ;
2017-06-19 18:23:48 +08:00
if ( on )
val = val | PCIE_ELBI_SLV_DBI_ENABLE ;
else
val = val & ~ PCIE_ELBI_SLV_DBI_ENABLE ;
2021-10-21 11:45:10 +01:00
regmap_write ( kirin_pcie - > apb , SOC_PCIECTRL_CTRL0_ADDR , val ) ;
2017-06-19 18:23:48 +08:00
}
static void kirin_pcie_sideband_dbi_r_mode ( struct kirin_pcie * kirin_pcie ,
bool on )
{
u32 val ;
2021-10-21 11:45:10 +01:00
regmap_read ( kirin_pcie - > apb , SOC_PCIECTRL_CTRL1_ADDR , & val ) ;
2017-06-19 18:23:48 +08:00
if ( on )
val = val | PCIE_ELBI_SLV_DBI_ENABLE ;
else
val = val & ~ PCIE_ELBI_SLV_DBI_ENABLE ;
2021-10-21 11:45:10 +01:00
regmap_write ( kirin_pcie - > apb , SOC_PCIECTRL_CTRL1_ADDR , val ) ;
2017-06-19 18:23:48 +08:00
}
2020-08-20 21:53:49 -06:00
static int kirin_pcie_rd_own_conf ( struct pci_bus * bus , unsigned int devfn ,
2017-06-19 18:23:48 +08:00
int where , int size , u32 * val )
{
2020-08-20 21:53:49 -06:00
struct dw_pcie * pci = to_dw_pcie_from_pp ( bus - > sysdata ) ;
2017-06-19 18:23:48 +08:00
2021-11-18 19:33:20 +05:30
if ( PCI_SLOT ( devfn ) )
2020-08-20 21:53:49 -06:00
return PCIBIOS_DEVICE_NOT_FOUND ;
2017-06-19 18:23:48 +08:00
2020-08-20 21:53:49 -06:00
* val = dw_pcie_read_dbi ( pci , where , size ) ;
return PCIBIOS_SUCCESSFUL ;
2017-06-19 18:23:48 +08:00
}
2020-08-20 21:53:49 -06:00
static int kirin_pcie_wr_own_conf ( struct pci_bus * bus , unsigned int devfn ,
2017-06-19 18:23:48 +08:00
int where , int size , u32 val )
{
2020-08-20 21:53:49 -06:00
struct dw_pcie * pci = to_dw_pcie_from_pp ( bus - > sysdata ) ;
2017-06-19 18:23:48 +08:00
2020-08-20 21:53:49 -06:00
if ( PCI_SLOT ( devfn ) )
return PCIBIOS_DEVICE_NOT_FOUND ;
2017-06-19 18:23:48 +08:00
2020-08-20 21:53:49 -06:00
dw_pcie_write_dbi ( pci , where , size , val ) ;
return PCIBIOS_SUCCESSFUL ;
2017-06-19 18:23:48 +08:00
}
2021-10-21 11:45:11 +01:00
static int kirin_pcie_add_bus ( struct pci_bus * bus )
{
struct dw_pcie * pci = to_dw_pcie_from_pp ( bus - > sysdata ) ;
struct kirin_pcie * kirin_pcie = to_kirin_pcie ( pci ) ;
int i , ret ;
if ( ! kirin_pcie - > num_slots )
return 0 ;
/* Send PERST# to each slot */
for ( i = 0 ; i < kirin_pcie - > num_slots ; i + + ) {
2024-05-06 17:20:41 +03:00
ret = gpiod_direction_output_raw ( kirin_pcie - > id_reset_gpio [ i ] , 1 ) ;
2021-10-21 11:45:11 +01:00
if ( ret ) {
dev_err ( pci - > dev , " PERST# %s error: %d \n " ,
kirin_pcie - > reset_names [ i ] , ret ) ;
}
}
usleep_range ( PERST_2_ACCESS_MIN , PERST_2_ACCESS_MAX ) ;
return 0 ;
}
2020-08-20 21:53:49 -06:00
static struct pci_ops kirin_pci_ops = {
. read = kirin_pcie_rd_own_conf ,
. write = kirin_pcie_wr_own_conf ,
2021-10-21 11:45:11 +01:00
. add_bus = kirin_pcie_add_bus ,
2020-08-20 21:53:49 -06:00
} ;
2017-06-19 18:23:48 +08:00
static u32 kirin_pcie_read_dbi ( struct dw_pcie * pci , void __iomem * base ,
u32 reg , size_t size )
{
struct kirin_pcie * kirin_pcie = to_kirin_pcie ( pci ) ;
u32 ret ;
kirin_pcie_sideband_dbi_r_mode ( kirin_pcie , true ) ;
dw_pcie_read ( base + reg , size , & ret ) ;
kirin_pcie_sideband_dbi_r_mode ( kirin_pcie , false ) ;
return ret ;
}
static void kirin_pcie_write_dbi ( struct dw_pcie * pci , void __iomem * base ,
u32 reg , size_t size , u32 val )
{
struct kirin_pcie * kirin_pcie = to_kirin_pcie ( pci ) ;
kirin_pcie_sideband_dbi_w_mode ( kirin_pcie , true ) ;
dw_pcie_write ( base + reg , size , val ) ;
kirin_pcie_sideband_dbi_w_mode ( kirin_pcie , false ) ;
}
static int kirin_pcie_link_up ( struct dw_pcie * pci )
{
struct kirin_pcie * kirin_pcie = to_kirin_pcie ( pci ) ;
2021-10-21 11:45:10 +01:00
u32 val ;
2017-06-19 18:23:48 +08:00
2021-10-21 11:45:10 +01:00
regmap_read ( kirin_pcie - > apb , PCIE_APB_PHY_STATUS0 , & val ) ;
2017-06-19 18:23:48 +08:00
if ( ( val & PCIE_LINKUP_ENABLE ) = = PCIE_LINKUP_ENABLE )
return 1 ;
return 0 ;
}
2020-11-05 15:11:53 -06:00
static int kirin_pcie_start_link ( struct dw_pcie * pci )
2017-06-19 18:23:48 +08:00
{
struct kirin_pcie * kirin_pcie = to_kirin_pcie ( pci ) ;
/* assert LTSSM enable */
2021-10-21 11:45:10 +01:00
regmap_write ( kirin_pcie - > apb , PCIE_APP_LTSSM_ENABLE ,
PCIE_LTSSM_ENABLE_BIT ) ;
2017-06-19 18:23:48 +08:00
return 0 ;
}
2022-06-24 17:34:25 +03:00
static int kirin_pcie_host_init ( struct dw_pcie_rp * pp )
2017-06-19 18:23:48 +08:00
{
2020-08-20 21:53:49 -06:00
pp - > bridge - > ops = & kirin_pci_ops ;
2017-07-15 23:39:45 -07:00
return 0 ;
2017-06-19 18:23:48 +08:00
}
2019-08-19 13:09:46 +05:30
static const struct dw_pcie_ops kirin_dw_pcie_ops = {
2017-06-19 18:23:48 +08:00
. read_dbi = kirin_pcie_read_dbi ,
. write_dbi = kirin_pcie_write_dbi ,
. link_up = kirin_pcie_link_up ,
2020-11-05 15:11:53 -06:00
. start_link = kirin_pcie_start_link ,
2017-06-19 18:23:48 +08:00
} ;
2017-08-09 13:18:48 +05:30
static const struct dw_pcie_host_ops kirin_pcie_host_ops = {
2023-12-20 14:38:24 +09:00
. init = kirin_pcie_host_init ,
2017-06-19 18:23:48 +08:00
} ;
2021-10-21 11:45:17 +01:00
static int kirin_pcie_power_off ( struct kirin_pcie * kirin_pcie )
{
int i ;
if ( kirin_pcie - > type = = PCIE_KIRIN_INTERNAL_PHY )
return hi3660_pcie_phy_power_off ( kirin_pcie ) ;
2021-10-21 11:45:18 +01:00
for ( i = 0 ; i < kirin_pcie - > n_gpio_clkreq ; i + + )
2024-05-06 17:20:41 +03:00
gpiod_direction_output_raw ( kirin_pcie - > id_clkreq_gpio [ i ] , 1 ) ;
2021-10-21 11:45:18 +01:00
2021-10-21 11:45:17 +01:00
phy_power_off ( kirin_pcie - > phy ) ;
phy_exit ( kirin_pcie - > phy ) ;
return 0 ;
}
2021-10-21 11:45:09 +01:00
static int kirin_pcie_power_on ( struct platform_device * pdev ,
struct kirin_pcie * kirin_pcie )
{
struct device * dev = & pdev - > dev ;
int ret ;
if ( kirin_pcie - > type = = PCIE_KIRIN_INTERNAL_PHY ) {
ret = hi3660_pcie_phy_init ( pdev , kirin_pcie ) ;
if ( ret )
return ret ;
2021-10-21 11:45:11 +01:00
ret = hi3660_pcie_phy_power_on ( kirin_pcie ) ;
if ( ret )
return ret ;
} else {
kirin_pcie - > phy = devm_of_phy_get ( dev , dev - > of_node , NULL ) ;
if ( IS_ERR ( kirin_pcie - > phy ) )
return PTR_ERR ( kirin_pcie - > phy ) ;
ret = phy_init ( kirin_pcie - > phy ) ;
if ( ret )
goto err ;
ret = phy_power_on ( kirin_pcie - > phy ) ;
if ( ret )
goto err ;
2021-10-21 11:45:09 +01:00
}
2021-10-21 11:45:11 +01:00
/* perst assert Endpoint */
usleep_range ( REF_2_PERST_MIN , REF_2_PERST_MAX ) ;
2021-10-21 11:45:09 +01:00
2024-05-06 17:20:41 +03:00
ret = gpiod_direction_output_raw ( kirin_pcie - > id_dwc_perst_gpio , 1 ) ;
if ( ret )
goto err ;
2021-10-21 11:45:09 +01:00
2021-10-21 11:45:11 +01:00
usleep_range ( PERST_2_ACCESS_MIN , PERST_2_ACCESS_MAX ) ;
2021-10-21 11:45:09 +01:00
return 0 ;
err :
2021-10-21 11:45:17 +01:00
kirin_pcie_power_off ( kirin_pcie ) ;
2021-10-21 11:45:11 +01:00
2021-10-21 11:45:09 +01:00
return ret ;
}
2023-12-04 10:47:42 +01:00
static void kirin_pcie_remove ( struct platform_device * pdev )
2021-10-21 11:45:09 +01:00
{
struct kirin_pcie * kirin_pcie = platform_get_drvdata ( pdev ) ;
2021-10-21 11:45:19 +01:00
dw_pcie_host_deinit ( & kirin_pcie - > pci - > pp ) ;
2021-10-21 11:45:17 +01:00
kirin_pcie_power_off ( kirin_pcie ) ;
2021-10-21 11:45:09 +01:00
}
2022-02-02 09:52:41 -06:00
struct kirin_pcie_data {
enum pcie_kirin_phy_type phy_type ;
} ;
static const struct kirin_pcie_data kirin_960_data = {
. phy_type = PCIE_KIRIN_INTERNAL_PHY ,
} ;
static const struct kirin_pcie_data kirin_970_data = {
. phy_type = PCIE_KIRIN_EXTERNAL_PHY ,
} ;
2021-10-21 11:45:09 +01:00
static const struct of_device_id kirin_pcie_match [ ] = {
2022-02-02 09:52:41 -06:00
{ . compatible = " hisilicon,kirin960-pcie " , . data = & kirin_960_data } ,
{ . compatible = " hisilicon,kirin970-pcie " , . data = & kirin_970_data } ,
2021-10-21 11:45:09 +01:00
{ } ,
} ;
2017-06-19 18:23:48 +08:00
static int kirin_pcie_probe ( struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
2022-02-02 09:52:41 -06:00
const struct kirin_pcie_data * data ;
2017-06-19 18:23:48 +08:00
struct kirin_pcie * kirin_pcie ;
struct dw_pcie * pci ;
int ret ;
if ( ! dev - > of_node ) {
dev_err ( dev , " NULL node \n " ) ;
return - EINVAL ;
}
2022-02-02 09:52:41 -06:00
data = of_device_get_match_data ( dev ) ;
if ( ! data ) {
2021-10-21 11:45:09 +01:00
dev_err ( dev , " OF data missing \n " ) ;
return - EINVAL ;
}
2017-06-19 18:23:48 +08:00
kirin_pcie = devm_kzalloc ( dev , sizeof ( struct kirin_pcie ) , GFP_KERNEL ) ;
if ( ! kirin_pcie )
return - ENOMEM ;
pci = devm_kzalloc ( dev , sizeof ( * pci ) , GFP_KERNEL ) ;
if ( ! pci )
return - ENOMEM ;
pci - > dev = dev ;
pci - > ops = & kirin_dw_pcie_ops ;
2020-11-05 15:11:56 -06:00
pci - > pp . ops = & kirin_pcie_host_ops ;
2017-06-19 18:23:48 +08:00
kirin_pcie - > pci = pci ;
2022-02-02 09:52:41 -06:00
kirin_pcie - > type = data - > phy_type ;
2017-06-19 18:23:48 +08:00
ret = kirin_pcie_get_resource ( kirin_pcie , pdev ) ;
if ( ret )
return ret ;
2021-10-21 11:45:09 +01:00
platform_set_drvdata ( pdev , kirin_pcie ) ;
ret = kirin_pcie_power_on ( pdev , kirin_pcie ) ;
2017-06-19 18:23:48 +08:00
if ( ret )
return ret ;
2020-11-05 15:11:56 -06:00
return dw_pcie_host_init ( & pci - > pp ) ;
2017-06-19 18:23:48 +08:00
}
2018-03-20 17:12:12 +00:00
static struct platform_driver kirin_pcie_driver = {
2017-06-19 18:23:48 +08:00
. probe = kirin_pcie_probe ,
2023-12-04 10:47:42 +01:00
. remove_new = kirin_pcie_remove ,
2017-06-19 18:23:48 +08:00
. driver = {
. name = " kirin-pcie " ,
2021-10-21 11:45:08 +01:00
. of_match_table = kirin_pcie_match ,
. suppress_bind_attrs = true ,
2017-06-19 18:23:48 +08:00
} ,
} ;
2021-10-21 11:45:20 +01:00
module_platform_driver ( kirin_pcie_driver ) ;
2021-10-21 11:45:14 +01:00
MODULE_DEVICE_TABLE ( of , kirin_pcie_match ) ;
MODULE_DESCRIPTION ( " PCIe host controller driver for Kirin Phone SoCs " ) ;
MODULE_AUTHOR ( " Xiaowei Song <songxiaowei@huawei.com> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;