Skip to content
Permalink
Browse files
net: wwan: t7xx: Add core components
Registers the t7xx device driver with the kernel. Setup all the core
components: PCIe layer, Modem Host Cross Core Interface (MHCCIF),
modem control operations, modem state machine, and build
infrastructure.

* PCIe layer code implements driver probe and removal.
* MHCCIF provides interrupt channels to communicate events
  such as handshake, PM and port enumeration.
* Modem control implements the entry point for modem init,
  reset and exit.
* The modem status monitor is a state machine used by modem control
  to complete initialization and stop. It is used also to propagate
  exception events reported by other components.

Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
Co-developed-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
Signed-off-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
  • Loading branch information
Haijun Liu authored and intel-lab-lkp committed Jan 14, 2022
1 parent a044d8c commit e62b3a8ab00c63ee38d0d31cd402a1a40e8b2769
Show file tree
Hide file tree
Showing 14 changed files with 2,325 additions and 0 deletions.
@@ -105,6 +105,20 @@ config IOSM

If unsure, say N.

config MTK_T7XX
tristate "MediaTek PCIe 5G WWAN modem T7xx device"
depends on PCI
help
Enables MediaTek PCIe based 5G WWAN modem (T7xx series) device.
Adapts WWAN framework and provides network interface like wwan0
and tty interfaces like wwan0at0 (AT protocol), wwan0mbim0
(MBIM protocol), etc.

To compile this driver as a module, choose M here: the module will be
called mtk_t7xx.

If unsure, say N.

endif # WWAN

endmenu
@@ -13,3 +13,4 @@ obj-$(CONFIG_MHI_WWAN_MBIM) += mhi_wwan_mbim.o
obj-$(CONFIG_QCOM_BAM_DMUX) += qcom_bam_dmux.o
obj-$(CONFIG_RPMSG_WWAN_CTRL) += rpmsg_wwan_ctrl.o
obj-$(CONFIG_IOSM) += iosm/
obj-$(CONFIG_MTK_T7XX) += t7xx/
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-only

ccflags-y += -Werror

obj-${CONFIG_MTK_T7XX} := mtk_t7xx.o
mtk_t7xx-y:= t7xx_pci.o \
t7xx_pcie_mac.o \
t7xx_mhccif.o \
t7xx_state_monitor.o \
t7xx_modem_ops.o \
t7xx_cldma.o \
t7xx_hif_cldma.o \
@@ -0,0 +1,98 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, MediaTek Inc.
* Copyright (c) 2021, Intel Corporation.
*
* Authors:
* Haijun Liu <haijun.liu@mediatek.com>
* Sreehari Kancharla <sreehari.kancharla@intel.com>
*
* Contributors:
* Amir Hanania <amir.hanania@intel.com>
* Ricardo Martinez<ricardo.martinez@linux.intel.com>
*/

#include <linux/bits.h>
#include <linux/completion.h>
#include <linux/dev_printk.h>
#include <linux/io.h>
#include <linux/irqreturn.h>

#include "t7xx_mhccif.h"
#include "t7xx_modem_ops.h"
#include "t7xx_pci.h"
#include "t7xx_pcie_mac.h"
#include "t7xx_reg.h"

static void t7xx_mhccif_clear_interrupts(struct t7xx_pci_dev *t7xx_dev, u32 mask)
{
void __iomem *mhccif_pbase = t7xx_dev->base_addr.mhccif_rc_base;

/* Clear level 2 interrupt */
iowrite32(mask, mhccif_pbase + REG_EP2RC_SW_INT_ACK);
/* Ensure write is complete */
t7xx_mhccif_read_sw_int_sts(t7xx_dev);
/* Clear level 1 interrupt */
t7xx_pcie_mac_clear_int_status(t7xx_dev, MHCCIF_INT);
}

static irqreturn_t t7xx_mhccif_isr_thread(int irq, void *data)
{
struct t7xx_pci_dev *t7xx_dev = data;
u32 int_sts, val;

val = L1_1_DISABLE_BIT(1) | L1_2_DISABLE_BIT(1);
iowrite32(val, IREG_BASE(t7xx_dev) + DIS_ASPM_LOWPWR_SET_0);

int_sts = t7xx_mhccif_read_sw_int_sts(t7xx_dev);
if (int_sts & t7xx_dev->mhccif_bitmask)
t7xx_pci_mhccif_isr(t7xx_dev);

t7xx_mhccif_clear_interrupts(t7xx_dev, int_sts);
t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT);
return IRQ_HANDLED;
}

u32 t7xx_mhccif_read_sw_int_sts(struct t7xx_pci_dev *t7xx_dev)
{
return ioread32(t7xx_dev->base_addr.mhccif_rc_base + REG_EP2RC_SW_INT_STS);
}

void t7xx_mhccif_mask_set(struct t7xx_pci_dev *t7xx_dev, u32 val)
{
iowrite32(val, t7xx_dev->base_addr.mhccif_rc_base + REG_EP2RC_SW_INT_EAP_MASK_SET);
}

void t7xx_mhccif_mask_clr(struct t7xx_pci_dev *t7xx_dev, u32 val)
{
iowrite32(val, t7xx_dev->base_addr.mhccif_rc_base + REG_EP2RC_SW_INT_EAP_MASK_CLR);
}

u32 t7xx_mhccif_mask_get(struct t7xx_pci_dev *t7xx_dev)
{
return ioread32(t7xx_dev->base_addr.mhccif_rc_base + REG_EP2RC_SW_INT_EAP_MASK);
}

static irqreturn_t t7xx_mhccif_isr_handler(int irq, void *data)
{
return IRQ_WAKE_THREAD;
}

void t7xx_mhccif_init(struct t7xx_pci_dev *t7xx_dev)
{
t7xx_dev->base_addr.mhccif_rc_base = t7xx_dev->base_addr.pcie_ext_reg_base +
MHCCIF_RC_DEV_BASE -
t7xx_dev->base_addr.pcie_dev_reg_trsl_addr;

t7xx_dev->intr_handler[MHCCIF_INT] = t7xx_mhccif_isr_handler;
t7xx_dev->intr_thread[MHCCIF_INT] = t7xx_mhccif_isr_thread;
t7xx_dev->callback_param[MHCCIF_INT] = t7xx_dev;
}

void t7xx_mhccif_h2d_swint_trigger(struct t7xx_pci_dev *t7xx_dev, u32 channel)
{
void __iomem *mhccif_pbase = t7xx_dev->base_addr.mhccif_rc_base;

iowrite32(BIT(channel), mhccif_pbase + REG_RC2EP_SW_BSY);
iowrite32(channel, mhccif_pbase + REG_RC2EP_SW_TCHNUM);
}
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2021, MediaTek Inc.
* Copyright (c) 2021, Intel Corporation.
*
* Authors:
* Haijun Liu <haijun.liu@mediatek.com>
* Sreehari Kancharla <sreehari.kancharla@intel.com>
*
* Contributors:
* Amir Hanania <amir.hanania@intel.com>
* Ricardo Martinez<ricardo.martinez@linux.intel.com>
*/

#ifndef __T7XX_MHCCIF_H__
#define __T7XX_MHCCIF_H__

#include <linux/types.h>

#include "t7xx_pci.h"
#include "t7xx_reg.h"

#define D2H_SW_INT_MASK (D2H_INT_EXCEPTION_INIT | \
D2H_INT_EXCEPTION_INIT_DONE | \
D2H_INT_EXCEPTION_CLEARQ_DONE | \
D2H_INT_EXCEPTION_ALLQ_RESET | \
D2H_INT_PORT_ENUM | \
D2H_INT_ASYNC_MD_HK)

void t7xx_mhccif_mask_set(struct t7xx_pci_dev *t7xx_dev, u32 val);
void t7xx_mhccif_mask_clr(struct t7xx_pci_dev *t7xx_dev, u32 val);
u32 t7xx_mhccif_mask_get(struct t7xx_pci_dev *t7xx_dev);
void t7xx_mhccif_init(struct t7xx_pci_dev *t7xx_dev);
u32 t7xx_mhccif_read_sw_int_sts(struct t7xx_pci_dev *t7xx_dev);
void t7xx_mhccif_h2d_swint_trigger(struct t7xx_pci_dev *t7xx_dev, u32 channel);

#endif /*__T7XX_MHCCIF_H__ */

0 comments on commit e62b3a8

Please sign in to comment.