Skip to content

Commit

Permalink
net: wwan: t7xx: Add core components
Browse files Browse the repository at this point in the history
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>
Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Haijun Liu authored and davem330 committed May 9, 2022
1 parent 39d4390 commit 13e920d
Show file tree
Hide file tree
Showing 14 changed files with 2,108 additions and 0 deletions.
14 changes: 14 additions & 0 deletions drivers/net/wwan/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions drivers/net/wwan/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/
12 changes: 12 additions & 0 deletions drivers/net/wwan/t7xx/Makefile
Original file line number Diff line number Diff line change
@@ -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 \
102 changes: 102 additions & 0 deletions drivers/net/wwan/t7xx/t7xx_mhccif.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, MediaTek Inc.
* Copyright (c) 2021-2022, 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_status, val;

val = T7XX_L1_1_BIT(1) | T7XX_L1_2_BIT(1);
iowrite32(val, IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR);

int_status = t7xx_mhccif_read_sw_int_sts(t7xx_dev);
if (int_status & D2H_SW_INT_MASK) {
int ret = t7xx_pci_mhccif_isr(t7xx_dev);

if (ret)
dev_err(&t7xx_dev->pdev->dev, "PCI MHCCIF ISR failure: %d", ret);
}

t7xx_mhccif_clear_interrupts(t7xx_dev, int_status);
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);
}
37 changes: 37 additions & 0 deletions drivers/net/wwan/t7xx/t7xx_mhccif.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2021, MediaTek Inc.
* Copyright (c) 2021-2022, 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__ */
Loading

0 comments on commit 13e920d

Please sign in to comment.