2018-03-28 18:46:15 +03:00
// SPDX-License-Identifier: GPL-2.0
2015-09-22 15:47:15 +03:00
/*
* Intel ( R ) Trace Hub pci driver
*
* Copyright ( C ) 2014 - 2015 Intel Corporation .
*/
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
# include <linux/types.h>
# include <linux/module.h>
# include <linux/device.h>
# include <linux/sysfs.h>
# include <linux/pci.h>
# include "intel_th.h"
# define DRIVER_NAME "intel_th_pci"
2019-05-03 11:44:36 +03:00
enum {
TH_PCI_CONFIG_BAR = 0 ,
TH_PCI_STH_SW_BAR = 2 ,
} ;
# define BAR_MASK (BIT(TH_PCI_CONFIG_BAR) | BIT(TH_PCI_STH_SW_BAR))
2015-09-22 15:47:15 +03:00
2017-02-24 16:09:40 +02:00
# define PCI_REG_NPKDSC 0x80
# define NPKDSC_TSACT BIT(5)
static int intel_th_pci_activate ( struct intel_th * th )
{
struct pci_dev * pdev = to_pci_dev ( th - > dev ) ;
u32 npkdsc ;
int err ;
if ( ! INTEL_TH_CAP ( th , tscu_enable ) )
return 0 ;
err = pci_read_config_dword ( pdev , PCI_REG_NPKDSC , & npkdsc ) ;
if ( ! err ) {
npkdsc | = NPKDSC_TSACT ;
err = pci_write_config_dword ( pdev , PCI_REG_NPKDSC , npkdsc ) ;
}
if ( err )
dev_err ( & pdev - > dev , " failed to read NPKDSC register \n " ) ;
return err ;
}
static void intel_th_pci_deactivate ( struct intel_th * th )
{
struct pci_dev * pdev = to_pci_dev ( th - > dev ) ;
u32 npkdsc ;
int err ;
if ( ! INTEL_TH_CAP ( th , tscu_enable ) )
return ;
err = pci_read_config_dword ( pdev , PCI_REG_NPKDSC , & npkdsc ) ;
if ( ! err ) {
npkdsc | = NPKDSC_TSACT ;
err = pci_write_config_dword ( pdev , PCI_REG_NPKDSC , npkdsc ) ;
}
if ( err )
dev_err ( & pdev - > dev , " failed to read NPKDSC register \n " ) ;
}
2015-09-22 15:47:15 +03:00
static int intel_th_pci_probe ( struct pci_dev * pdev ,
const struct pci_device_id * id )
{
2017-08-18 17:57:35 +03:00
struct intel_th_drvdata * drvdata = ( void * ) id - > driver_data ;
2019-05-03 11:44:36 +03:00
struct resource resource [ TH_MMIO_END ] = {
[ TH_MMIO_CONFIG ] = pdev - > resource [ TH_PCI_CONFIG_BAR ] ,
[ TH_MMIO_SW ] = pdev - > resource [ TH_PCI_STH_SW_BAR ] ,
} ;
2015-09-22 15:47:15 +03:00
struct intel_th * th ;
int err ;
err = pcim_enable_device ( pdev ) ;
if ( err )
return err ;
err = pcim_iomap_regions_request_all ( pdev , BAR_MASK , DRIVER_NAME ) ;
if ( err )
return err ;
2019-05-03 11:44:36 +03:00
th = intel_th_alloc ( & pdev - > dev , drvdata , resource , TH_MMIO_END ,
pdev - > irq ) ;
2015-09-22 15:47:15 +03:00
if ( IS_ERR ( th ) )
return PTR_ERR ( th ) ;
2017-02-24 16:09:40 +02:00
th - > activate = intel_th_pci_activate ;
th - > deactivate = intel_th_pci_deactivate ;
2017-08-10 11:10:58 +03:00
pci_set_master ( pdev ) ;
2015-09-22 15:47:15 +03:00
return 0 ;
}
static void intel_th_pci_remove ( struct pci_dev * pdev )
{
struct intel_th * th = pci_get_drvdata ( pdev ) ;
intel_th_free ( th ) ;
}
2017-02-24 16:09:40 +02:00
static const struct intel_th_drvdata intel_th_2x = {
. tscu_enable = 1 ,
} ;
2015-09-22 15:47:15 +03:00
static const struct pci_device_id intel_th_pci_id_table [ ] = {
{
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x9d26 ) ,
. driver_data = ( kernel_ulong_t ) 0 ,
} ,
{
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0xa126 ) ,
. driver_data = ( kernel_ulong_t ) 0 ,
} ,
2015-12-22 17:25:22 +02:00
{
/* Apollo Lake */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x5a8e ) ,
. driver_data = ( kernel_ulong_t ) 0 ,
} ,
2015-12-22 17:25:23 +02:00
{
/* Broxton */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x0a80 ) ,
. driver_data = ( kernel_ulong_t ) 0 ,
} ,
2016-04-08 18:26:52 +03:00
{
/* Broxton B-step */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x1a8e ) ,
. driver_data = ( kernel_ulong_t ) 0 ,
} ,
2016-06-28 18:55:23 +03:00
{
/* Kaby Lake PCH-H */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0xa2a6 ) ,
. driver_data = ( kernel_ulong_t ) 0 ,
} ,
2015-09-08 14:03:55 +03:00
{
/* Denverton */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x19e1 ) ,
. driver_data = ( kernel_ulong_t ) 0 ,
} ,
2017-09-19 18:47:42 +03:00
{
/* Lewisburg PCH */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0xa1a6 ) ,
. driver_data = ( kernel_ulong_t ) 0 ,
} ,
2016-06-30 16:10:51 +03:00
{
/* Gemini Lake */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x318e ) ,
2017-02-24 16:09:40 +02:00
. driver_data = ( kernel_ulong_t ) & intel_th_2x ,
2016-06-30 16:10:51 +03:00
} ,
2016-06-30 16:11:13 +03:00
{
/* Cannon Lake H */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0xa326 ) ,
2017-02-24 16:09:40 +02:00
. driver_data = ( kernel_ulong_t ) & intel_th_2x ,
2016-06-30 16:11:13 +03:00
} ,
2016-06-30 16:11:31 +03:00
{
/* Cannon Lake LP */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x9da6 ) ,
2017-02-24 16:09:40 +02:00
. driver_data = ( kernel_ulong_t ) & intel_th_2x ,
2016-06-30 16:11:31 +03:00
} ,
2017-09-19 18:47:41 +03:00
{
/* Cedar Fork PCH */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x18e1 ) ,
. driver_data = ( kernel_ulong_t ) & intel_th_2x ,
} ,
2018-09-18 16:10:49 +03:00
{
/* Ice Lake PCH */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x34a6 ) ,
. driver_data = ( kernel_ulong_t ) & intel_th_2x ,
} ,
2015-09-22 15:47:15 +03:00
{ 0 } ,
} ;
MODULE_DEVICE_TABLE ( pci , intel_th_pci_id_table ) ;
static struct pci_driver intel_th_pci_driver = {
. name = DRIVER_NAME ,
. id_table = intel_th_pci_id_table ,
. probe = intel_th_pci_probe ,
. remove = intel_th_pci_remove ,
} ;
module_pci_driver ( intel_th_pci_driver ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_DESCRIPTION ( " Intel(R) Trace Hub PCI controller driver " ) ;
MODULE_AUTHOR ( " Alexander Shishkin <alexander.shishkin@intel.com> " ) ;