brintos

brintos / linux-shallow public Read only

0
0
Text · 43.6 KiB · 9938bb0 Raw
1488 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * MHI PCI driver - MHI over PCI controller driver4 *5 * This module is a generic driver for registering MHI-over-PCI devices,6 * such as PCIe QCOM modems.7 *8 * Copyright (C) 2020 Linaro Ltd <loic.poulain@linaro.org>9 */10 11#include <linux/delay.h>12#include <linux/device.h>13#include <linux/mhi.h>14#include <linux/module.h>15#include <linux/pci.h>16#include <linux/pm_runtime.h>17#include <linux/timer.h>18#include <linux/workqueue.h>19 20#define MHI_PCI_DEFAULT_BAR_NUM 021 22#define MHI_POST_RESET_DELAY_MS 200023 24#define HEALTH_CHECK_PERIOD (HZ * 2)25 26/* PCI VID definitions */27#define PCI_VENDOR_ID_THALES	0x126928#define PCI_VENDOR_ID_QUECTEL	0x1eac29#define PCI_VENDOR_ID_NETPRISMA	0x203e30 31#define MHI_EDL_DB			9132#define MHI_EDL_COOKIE			0xEDEDEDED33 34/**35 * struct mhi_pci_dev_info - MHI PCI device specific information36 * @config: MHI controller configuration37 * @name: name of the PCI module38 * @fw: firmware path (if any)39 * @edl: emergency download mode firmware path (if any)40 * @edl_trigger: capable of triggering EDL mode in the device (if supported)41 * @bar_num: PCI base address register to use for MHI MMIO register space42 * @dma_data_width: DMA transfer word size (32 or 64 bits)43 * @mru_default: default MRU size for MBIM network packets44 * @sideband_wake: Devices using dedicated sideband GPIO for wakeup instead45 *		   of inband wake support (such as sdx24)46 */47struct mhi_pci_dev_info {48	const struct mhi_controller_config *config;49	const char *name;50	const char *fw;51	const char *edl;52	bool edl_trigger;53	unsigned int bar_num;54	unsigned int dma_data_width;55	unsigned int mru_default;56	bool sideband_wake;57};58 59#define MHI_CHANNEL_CONFIG_UL(ch_num, ch_name, el_count, ev_ring) \60	{						\61		.num = ch_num,				\62		.name = ch_name,			\63		.num_elements = el_count,		\64		.event_ring = ev_ring,			\65		.dir = DMA_TO_DEVICE,			\66		.ee_mask = BIT(MHI_EE_AMSS),		\67		.pollcfg = 0,				\68		.doorbell = MHI_DB_BRST_DISABLE,	\69		.lpm_notify = false,			\70		.offload_channel = false,		\71		.doorbell_mode_switch = false,		\72	}						\73 74#define MHI_CHANNEL_CONFIG_DL(ch_num, ch_name, el_count, ev_ring) \75	{						\76		.num = ch_num,				\77		.name = ch_name,			\78		.num_elements = el_count,		\79		.event_ring = ev_ring,			\80		.dir = DMA_FROM_DEVICE,			\81		.ee_mask = BIT(MHI_EE_AMSS),		\82		.pollcfg = 0,				\83		.doorbell = MHI_DB_BRST_DISABLE,	\84		.lpm_notify = false,			\85		.offload_channel = false,		\86		.doorbell_mode_switch = false,		\87	}88 89#define MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(ch_num, ch_name, el_count, ev_ring) \90	{						\91		.num = ch_num,				\92		.name = ch_name,			\93		.num_elements = el_count,		\94		.event_ring = ev_ring,			\95		.dir = DMA_FROM_DEVICE,			\96		.ee_mask = BIT(MHI_EE_AMSS),		\97		.pollcfg = 0,				\98		.doorbell = MHI_DB_BRST_DISABLE,	\99		.lpm_notify = false,			\100		.offload_channel = false,		\101		.doorbell_mode_switch = false,		\102		.auto_queue = true,			\103	}104 105#define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \106	{					\107		.num_elements = el_count,	\108		.irq_moderation_ms = 0,		\109		.irq = (ev_ring) + 1,		\110		.priority = 1,			\111		.mode = MHI_DB_BRST_DISABLE,	\112		.data_type = MHI_ER_CTRL,	\113		.hardware_event = false,	\114		.client_managed = false,	\115		.offload_channel = false,	\116	}117 118#define MHI_CHANNEL_CONFIG_HW_UL(ch_num, ch_name, el_count, ev_ring) \119	{						\120		.num = ch_num,				\121		.name = ch_name,			\122		.num_elements = el_count,		\123		.event_ring = ev_ring,			\124		.dir = DMA_TO_DEVICE,			\125		.ee_mask = BIT(MHI_EE_AMSS),		\126		.pollcfg = 0,				\127		.doorbell = MHI_DB_BRST_ENABLE,	\128		.lpm_notify = false,			\129		.offload_channel = false,		\130		.doorbell_mode_switch = true,		\131	}						\132 133#define MHI_CHANNEL_CONFIG_HW_DL(ch_num, ch_name, el_count, ev_ring) \134	{						\135		.num = ch_num,				\136		.name = ch_name,			\137		.num_elements = el_count,		\138		.event_ring = ev_ring,			\139		.dir = DMA_FROM_DEVICE,			\140		.ee_mask = BIT(MHI_EE_AMSS),		\141		.pollcfg = 0,				\142		.doorbell = MHI_DB_BRST_ENABLE,	\143		.lpm_notify = false,			\144		.offload_channel = false,		\145		.doorbell_mode_switch = true,		\146	}147 148#define MHI_CHANNEL_CONFIG_UL_SBL(ch_num, ch_name, el_count, ev_ring) \149	{						\150		.num = ch_num,				\151		.name = ch_name,			\152		.num_elements = el_count,		\153		.event_ring = ev_ring,			\154		.dir = DMA_TO_DEVICE,			\155		.ee_mask = BIT(MHI_EE_SBL),		\156		.pollcfg = 0,				\157		.doorbell = MHI_DB_BRST_DISABLE,	\158		.lpm_notify = false,			\159		.offload_channel = false,		\160		.doorbell_mode_switch = false,		\161	}						\162 163#define MHI_CHANNEL_CONFIG_DL_SBL(ch_num, ch_name, el_count, ev_ring) \164	{						\165		.num = ch_num,				\166		.name = ch_name,			\167		.num_elements = el_count,		\168		.event_ring = ev_ring,			\169		.dir = DMA_FROM_DEVICE,			\170		.ee_mask = BIT(MHI_EE_SBL),		\171		.pollcfg = 0,				\172		.doorbell = MHI_DB_BRST_DISABLE,	\173		.lpm_notify = false,			\174		.offload_channel = false,		\175		.doorbell_mode_switch = false,		\176	}177 178#define MHI_CHANNEL_CONFIG_UL_FP(ch_num, ch_name, el_count, ev_ring) \179	{						\180		.num = ch_num,				\181		.name = ch_name,			\182		.num_elements = el_count,		\183		.event_ring = ev_ring,			\184		.dir = DMA_TO_DEVICE,			\185		.ee_mask = BIT(MHI_EE_FP),		\186		.pollcfg = 0,				\187		.doorbell = MHI_DB_BRST_DISABLE,	\188		.lpm_notify = false,			\189		.offload_channel = false,		\190		.doorbell_mode_switch = false,		\191	}						\192 193#define MHI_CHANNEL_CONFIG_DL_FP(ch_num, ch_name, el_count, ev_ring) \194	{						\195		.num = ch_num,				\196		.name = ch_name,			\197		.num_elements = el_count,		\198		.event_ring = ev_ring,			\199		.dir = DMA_FROM_DEVICE,			\200		.ee_mask = BIT(MHI_EE_FP),		\201		.pollcfg = 0,				\202		.doorbell = MHI_DB_BRST_DISABLE,	\203		.lpm_notify = false,			\204		.offload_channel = false,		\205		.doorbell_mode_switch = false,		\206	}207 208#define MHI_EVENT_CONFIG_DATA(ev_ring, el_count) \209	{					\210		.num_elements = el_count,	\211		.irq_moderation_ms = 5,		\212		.irq = (ev_ring) + 1,		\213		.priority = 1,			\214		.mode = MHI_DB_BRST_DISABLE,	\215		.data_type = MHI_ER_DATA,	\216		.hardware_event = false,	\217		.client_managed = false,	\218		.offload_channel = false,	\219	}220 221#define MHI_EVENT_CONFIG_SW_DATA(ev_ring, el_count) \222	{					\223		.num_elements = el_count,	\224		.irq_moderation_ms = 0,		\225		.irq = (ev_ring) + 1,		\226		.priority = 1,			\227		.mode = MHI_DB_BRST_DISABLE,	\228		.data_type = MHI_ER_DATA,	\229		.hardware_event = false,	\230		.client_managed = false,	\231		.offload_channel = false,	\232	}233 234#define MHI_EVENT_CONFIG_HW_DATA(ev_ring, el_count, ch_num) \235	{					\236		.num_elements = el_count,	\237		.irq_moderation_ms = 1,		\238		.irq = (ev_ring) + 1,		\239		.priority = 1,			\240		.mode = MHI_DB_BRST_DISABLE,	\241		.data_type = MHI_ER_DATA,	\242		.hardware_event = true,		\243		.client_managed = false,	\244		.offload_channel = false,	\245		.channel = ch_num,		\246	}247 248static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = {249	MHI_CHANNEL_CONFIG_UL(4, "DIAG", 16, 1),250	MHI_CHANNEL_CONFIG_DL(5, "DIAG", 16, 1),251	MHI_CHANNEL_CONFIG_UL(12, "MBIM", 4, 0),252	MHI_CHANNEL_CONFIG_DL(13, "MBIM", 4, 0),253	MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0),254	MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0),255	MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0),256	MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0),257	MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0),258	MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),259	MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 64, 2),260	MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 64, 3),261	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 4),262	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 5),263};264 265static struct mhi_event_config modem_qcom_v1_mhi_events[] = {266	/* first ring is control+data ring */267	MHI_EVENT_CONFIG_CTRL(0, 64),268	/* DIAG dedicated event ring */269	MHI_EVENT_CONFIG_DATA(1, 128),270	/* Software channels dedicated event ring */271	MHI_EVENT_CONFIG_SW_DATA(2, 64),272	MHI_EVENT_CONFIG_SW_DATA(3, 64),273	/* Hardware channels request dedicated hardware event rings */274	MHI_EVENT_CONFIG_HW_DATA(4, 1024, 100),275	MHI_EVENT_CONFIG_HW_DATA(5, 2048, 101)276};277 278static const struct mhi_controller_config modem_qcom_v2_mhiv_config = {279	.max_channels = 128,280	.timeout_ms = 8000,281	.ready_timeout_ms = 50000,282	.num_channels = ARRAY_SIZE(modem_qcom_v1_mhi_channels),283	.ch_cfg = modem_qcom_v1_mhi_channels,284	.num_events = ARRAY_SIZE(modem_qcom_v1_mhi_events),285	.event_cfg = modem_qcom_v1_mhi_events,286};287 288static const struct mhi_controller_config modem_qcom_v1_mhiv_config = {289	.max_channels = 128,290	.timeout_ms = 8000,291	.num_channels = ARRAY_SIZE(modem_qcom_v1_mhi_channels),292	.ch_cfg = modem_qcom_v1_mhi_channels,293	.num_events = ARRAY_SIZE(modem_qcom_v1_mhi_events),294	.event_cfg = modem_qcom_v1_mhi_events,295};296 297static const struct mhi_pci_dev_info mhi_qcom_sdx75_info = {298	.name = "qcom-sdx75m",299	.fw = "qcom/sdx75m/xbl.elf",300	.edl = "qcom/sdx75m/edl.mbn",301	.edl_trigger = true,302	.config = &modem_qcom_v2_mhiv_config,303	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,304	.dma_data_width = 32,305	.sideband_wake = false,306};307 308static const struct mhi_pci_dev_info mhi_qcom_sdx65_info = {309	.name = "qcom-sdx65m",310	.fw = "qcom/sdx65m/xbl.elf",311	.edl = "qcom/sdx65m/edl.mbn",312	.edl_trigger = true,313	.config = &modem_qcom_v1_mhiv_config,314	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,315	.dma_data_width = 32,316	.sideband_wake = false,317};318 319static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = {320	.name = "qcom-sdx55m",321	.fw = "qcom/sdx55m/sbl1.mbn",322	.edl = "qcom/sdx55m/edl.mbn",323	.edl_trigger = true,324	.config = &modem_qcom_v1_mhiv_config,325	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,326	.dma_data_width = 32,327	.mru_default = 32768,328	.sideband_wake = false,329};330 331static const struct mhi_pci_dev_info mhi_qcom_sdx24_info = {332	.name = "qcom-sdx24",333	.edl = "qcom/prog_firehose_sdx24.mbn",334	.config = &modem_qcom_v1_mhiv_config,335	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,336	.dma_data_width = 32,337	.sideband_wake = true,338};339 340static const struct mhi_channel_config mhi_quectel_em1xx_channels[] = {341	MHI_CHANNEL_CONFIG_UL(0, "NMEA", 32, 0),342	MHI_CHANNEL_CONFIG_DL(1, "NMEA", 32, 0),343	MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0),344	MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 32, 0),345	MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 1),346	MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 1),347	MHI_CHANNEL_CONFIG_UL(12, "MBIM", 32, 0),348	MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0),349	MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),350	MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),351	/* The EDL firmware is a flash-programmer exposing firehose protocol */352	MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0),353	MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),354	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2),355	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),356};357 358static struct mhi_event_config mhi_quectel_em1xx_events[] = {359	MHI_EVENT_CONFIG_CTRL(0, 128),360	MHI_EVENT_CONFIG_DATA(1, 128),361	MHI_EVENT_CONFIG_HW_DATA(2, 1024, 100),362	MHI_EVENT_CONFIG_HW_DATA(3, 1024, 101)363};364 365static const struct mhi_controller_config modem_quectel_em1xx_config = {366	.max_channels = 128,367	.timeout_ms = 20000,368	.num_channels = ARRAY_SIZE(mhi_quectel_em1xx_channels),369	.ch_cfg = mhi_quectel_em1xx_channels,370	.num_events = ARRAY_SIZE(mhi_quectel_em1xx_events),371	.event_cfg = mhi_quectel_em1xx_events,372};373 374static const struct mhi_pci_dev_info mhi_quectel_em1xx_info = {375	.name = "quectel-em1xx",376	.edl = "qcom/prog_firehose_sdx24.mbn",377	.config = &modem_quectel_em1xx_config,378	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,379	.dma_data_width = 32,380	.mru_default = 32768,381	.sideband_wake = true,382};383 384static const struct mhi_pci_dev_info mhi_quectel_rm5xx_info = {385	.name = "quectel-rm5xx",386	.edl = "qcom/prog_firehose_sdx6x.elf",387	.config = &modem_quectel_em1xx_config,388	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,389	.dma_data_width = 32,390	.mru_default = 32768,391	.sideband_wake = true,392};393 394static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = {395	MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 32, 0),396	MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 32, 0),397	MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 1),398	MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 1),399	MHI_CHANNEL_CONFIG_UL(12, "MBIM", 32, 0),400	MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0),401	MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),402	MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),403	MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0),404	MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),405	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2),406	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),407};408 409static struct mhi_event_config mhi_foxconn_sdx55_events[] = {410	MHI_EVENT_CONFIG_CTRL(0, 128),411	MHI_EVENT_CONFIG_DATA(1, 128),412	MHI_EVENT_CONFIG_HW_DATA(2, 1024, 100),413	MHI_EVENT_CONFIG_HW_DATA(3, 1024, 101)414};415 416static const struct mhi_controller_config modem_foxconn_sdx55_config = {417	.max_channels = 128,418	.timeout_ms = 20000,419	.num_channels = ARRAY_SIZE(mhi_foxconn_sdx55_channels),420	.ch_cfg = mhi_foxconn_sdx55_channels,421	.num_events = ARRAY_SIZE(mhi_foxconn_sdx55_events),422	.event_cfg = mhi_foxconn_sdx55_events,423};424 425static const struct mhi_controller_config modem_foxconn_sdx72_config = {426	.max_channels = 128,427	.timeout_ms = 20000,428	.ready_timeout_ms = 50000,429	.num_channels = ARRAY_SIZE(mhi_foxconn_sdx55_channels),430	.ch_cfg = mhi_foxconn_sdx55_channels,431	.num_events = ARRAY_SIZE(mhi_foxconn_sdx55_events),432	.event_cfg = mhi_foxconn_sdx55_events,433};434 435static const struct mhi_pci_dev_info mhi_foxconn_sdx55_info = {436	.name = "foxconn-sdx55",437	.edl = "qcom/sdx55m/foxconn/prog_firehose_sdx55.mbn",438	.edl_trigger = true,439	.config = &modem_foxconn_sdx55_config,440	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,441	.dma_data_width = 32,442	.mru_default = 32768,443	.sideband_wake = false,444};445 446static const struct mhi_pci_dev_info mhi_foxconn_t99w175_info = {447	.name = "foxconn-t99w175",448	.edl = "qcom/sdx55m/foxconn/prog_firehose_sdx55.mbn",449	.edl_trigger = true,450	.config = &modem_foxconn_sdx55_config,451	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,452	.dma_data_width = 32,453	.mru_default = 32768,454	.sideband_wake = false,455};456 457static const struct mhi_pci_dev_info mhi_foxconn_dw5930e_info = {458	.name = "foxconn-dw5930e",459	.edl = "qcom/sdx55m/foxconn/prog_firehose_sdx55.mbn",460	.edl_trigger = true,461	.config = &modem_foxconn_sdx55_config,462	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,463	.dma_data_width = 32,464	.mru_default = 32768,465	.sideband_wake = false,466};467 468static const struct mhi_pci_dev_info mhi_foxconn_t99w368_info = {469	.name = "foxconn-t99w368",470	.edl = "qcom/sdx65m/foxconn/prog_firehose_lite.elf",471	.edl_trigger = true,472	.config = &modem_foxconn_sdx55_config,473	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,474	.dma_data_width = 32,475	.mru_default = 32768,476	.sideband_wake = false,477};478 479static const struct mhi_pci_dev_info mhi_foxconn_t99w373_info = {480	.name = "foxconn-t99w373",481	.edl = "qcom/sdx65m/foxconn/prog_firehose_lite.elf",482	.edl_trigger = true,483	.config = &modem_foxconn_sdx55_config,484	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,485	.dma_data_width = 32,486	.mru_default = 32768,487	.sideband_wake = false,488};489 490static const struct mhi_pci_dev_info mhi_foxconn_t99w510_info = {491	.name = "foxconn-t99w510",492	.edl = "qcom/sdx24m/foxconn/prog_firehose_sdx24.mbn",493	.edl_trigger = true,494	.config = &modem_foxconn_sdx55_config,495	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,496	.dma_data_width = 32,497	.mru_default = 32768,498	.sideband_wake = false,499};500 501static const struct mhi_pci_dev_info mhi_foxconn_dw5932e_info = {502	.name = "foxconn-dw5932e",503	.edl = "qcom/sdx65m/foxconn/prog_firehose_lite.elf",504	.edl_trigger = true,505	.config = &modem_foxconn_sdx55_config,506	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,507	.dma_data_width = 32,508	.mru_default = 32768,509	.sideband_wake = false,510};511 512static const struct mhi_pci_dev_info mhi_foxconn_t99w515_info = {513	.name = "foxconn-t99w515",514	.edl = "qcom/sdx72m/foxconn/edl.mbn",515	.edl_trigger = true,516	.config = &modem_foxconn_sdx72_config,517	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,518	.dma_data_width = 32,519	.mru_default = 32768,520	.sideband_wake = false,521};522 523static const struct mhi_pci_dev_info mhi_foxconn_dw5934e_info = {524	.name = "foxconn-dw5934e",525	.edl = "qcom/sdx72m/foxconn/edl.mbn",526	.edl_trigger = true,527	.config = &modem_foxconn_sdx72_config,528	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,529	.dma_data_width = 32,530	.mru_default = 32768,531	.sideband_wake = false,532};533 534static const struct mhi_channel_config mhi_mv3x_channels[] = {535	MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 64, 0),536	MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 64, 0),537	/* MBIM Control Channel */538	MHI_CHANNEL_CONFIG_UL(12, "MBIM", 64, 0),539	MHI_CHANNEL_CONFIG_DL(13, "MBIM", 64, 0),540	/* MBIM Data Channel */541	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 512, 2),542	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 512, 3),543};544 545static struct mhi_event_config mhi_mv3x_events[] = {546	MHI_EVENT_CONFIG_CTRL(0, 256),547	MHI_EVENT_CONFIG_DATA(1, 256),548	MHI_EVENT_CONFIG_HW_DATA(2, 1024, 100),549	MHI_EVENT_CONFIG_HW_DATA(3, 1024, 101),550};551 552static const struct mhi_controller_config modem_mv3x_config = {553	.max_channels = 128,554	.timeout_ms = 20000,555	.num_channels = ARRAY_SIZE(mhi_mv3x_channels),556	.ch_cfg = mhi_mv3x_channels,557	.num_events = ARRAY_SIZE(mhi_mv3x_events),558	.event_cfg = mhi_mv3x_events,559};560 561static const struct mhi_pci_dev_info mhi_mv31_info = {562	.name = "cinterion-mv31",563	.config = &modem_mv3x_config,564	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,565	.dma_data_width = 32,566	.mru_default = 32768,567};568 569static const struct mhi_pci_dev_info mhi_mv32_info = {570	.name = "cinterion-mv32",571	.config = &modem_mv3x_config,572	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,573	.dma_data_width = 32,574	.mru_default = 32768,575};576 577static const struct mhi_channel_config mhi_sierra_em919x_channels[] = {578	MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0),579	MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 256, 0),580	MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 0),581	MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 0),582	MHI_CHANNEL_CONFIG_UL(12, "MBIM", 128, 0),583	MHI_CHANNEL_CONFIG_DL(13, "MBIM", 128, 0),584	MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0),585	MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0),586	MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),587	MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),588	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 512, 1),589	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 512, 2),590};591 592static struct mhi_event_config modem_sierra_em919x_mhi_events[] = {593	/* first ring is control+data and DIAG ring */594	MHI_EVENT_CONFIG_CTRL(0, 2048),595	/* Hardware channels request dedicated hardware event rings */596	MHI_EVENT_CONFIG_HW_DATA(1, 2048, 100),597	MHI_EVENT_CONFIG_HW_DATA(2, 2048, 101)598};599 600static const struct mhi_controller_config modem_sierra_em919x_config = {601	.max_channels = 128,602	.timeout_ms = 24000,603	.num_channels = ARRAY_SIZE(mhi_sierra_em919x_channels),604	.ch_cfg = mhi_sierra_em919x_channels,605	.num_events = ARRAY_SIZE(modem_sierra_em919x_mhi_events),606	.event_cfg = modem_sierra_em919x_mhi_events,607};608 609static const struct mhi_pci_dev_info mhi_sierra_em919x_info = {610	.name = "sierra-em919x",611	.config = &modem_sierra_em919x_config,612	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,613	.dma_data_width = 32,614	.sideband_wake = false,615};616 617static const struct mhi_channel_config mhi_telit_fn980_hw_v1_channels[] = {618	MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0),619	MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0),620	MHI_CHANNEL_CONFIG_UL(20, "IPCR", 16, 0),621	MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 16, 0),622	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 1),623	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 2),624};625 626static struct mhi_event_config mhi_telit_fn980_hw_v1_events[] = {627	MHI_EVENT_CONFIG_CTRL(0, 128),628	MHI_EVENT_CONFIG_HW_DATA(1, 1024, 100),629	MHI_EVENT_CONFIG_HW_DATA(2, 2048, 101)630};631 632static const struct mhi_controller_config modem_telit_fn980_hw_v1_config = {633	.max_channels = 128,634	.timeout_ms = 20000,635	.num_channels = ARRAY_SIZE(mhi_telit_fn980_hw_v1_channels),636	.ch_cfg = mhi_telit_fn980_hw_v1_channels,637	.num_events = ARRAY_SIZE(mhi_telit_fn980_hw_v1_events),638	.event_cfg = mhi_telit_fn980_hw_v1_events,639};640 641static const struct mhi_pci_dev_info mhi_telit_fn980_hw_v1_info = {642	.name = "telit-fn980-hwv1",643	.fw = "qcom/sdx55m/sbl1.mbn",644	.edl = "qcom/sdx55m/edl.mbn",645	.config = &modem_telit_fn980_hw_v1_config,646	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,647	.dma_data_width = 32,648	.mru_default = 32768,649	.sideband_wake = false,650};651 652static const struct mhi_channel_config mhi_telit_fn990_channels[] = {653	MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0),654	MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 32, 0),655	MHI_CHANNEL_CONFIG_UL(4, "DIAG", 64, 1),656	MHI_CHANNEL_CONFIG_DL(5, "DIAG", 64, 1),657	MHI_CHANNEL_CONFIG_UL(12, "MBIM", 32, 0),658	MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0),659	MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),660	MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),661	MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1),662	MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1),663	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2),664	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),665};666 667static struct mhi_event_config mhi_telit_fn990_events[] = {668	MHI_EVENT_CONFIG_CTRL(0, 128),669	MHI_EVENT_CONFIG_DATA(1, 128),670	MHI_EVENT_CONFIG_HW_DATA(2, 1024, 100),671	MHI_EVENT_CONFIG_HW_DATA(3, 2048, 101)672};673 674static const struct mhi_controller_config modem_telit_fn990_config = {675	.max_channels = 128,676	.timeout_ms = 20000,677	.num_channels = ARRAY_SIZE(mhi_telit_fn990_channels),678	.ch_cfg = mhi_telit_fn990_channels,679	.num_events = ARRAY_SIZE(mhi_telit_fn990_events),680	.event_cfg = mhi_telit_fn990_events,681};682 683static const struct mhi_pci_dev_info mhi_telit_fn990_info = {684	.name = "telit-fn990",685	.config = &modem_telit_fn990_config,686	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,687	.dma_data_width = 32,688	.sideband_wake = false,689	.mru_default = 32768,690};691 692static const struct mhi_pci_dev_info mhi_telit_fe990a_info = {693	.name = "telit-fe990a",694	.config = &modem_telit_fn990_config,695	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,696	.dma_data_width = 32,697	.sideband_wake = false,698	.mru_default = 32768,699};700 701static const struct mhi_pci_dev_info mhi_netprisma_lcur57_info = {702	.name = "netprisma-lcur57",703	.edl = "qcom/prog_firehose_sdx24.mbn",704	.config = &modem_quectel_em1xx_config,705	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,706	.dma_data_width = 32,707	.mru_default = 32768,708	.sideband_wake = true,709};710 711static const struct mhi_pci_dev_info mhi_netprisma_fcun69_info = {712	.name = "netprisma-fcun69",713	.edl = "qcom/prog_firehose_sdx6x.elf",714	.config = &modem_quectel_em1xx_config,715	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,716	.dma_data_width = 32,717	.mru_default = 32768,718	.sideband_wake = true,719};720 721/* Keep the list sorted based on the PID. New VID should be added as the last entry */722static const struct pci_device_id mhi_pci_id_table[] = {723	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304),724		.driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info },725	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c),726		.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info },727	/* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */728	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200),729		.driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info },730	/* Telit FN980 hardware revision v1 */731	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x1C5D, 0x2000),732		.driver_data = (kernel_ulong_t) &mhi_telit_fn980_hw_v1_info },733	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0306),734		.driver_data = (kernel_ulong_t) &mhi_qcom_sdx55_info },735	/* Telit FN990 */736	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010),737		.driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },738	/* Telit FE990A */739	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015),740		.driver_data = (kernel_ulong_t) &mhi_telit_fe990a_info },741	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),742		.driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },743	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0309),744		.driver_data = (kernel_ulong_t) &mhi_qcom_sdx75_info },745	{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1001), /* EM120R-GL (sdx24) */746		.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },747	{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */748		.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },749	/* RM520N-GL (sdx6x), eSIM */750	{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1004),751		.driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info },752	/* RM520N-GL (sdx6x), Lenovo variant */753	{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1007),754		.driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info },755	{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x100d), /* EM160R-GL (sdx24) */756		.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },757	{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */758		.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },759	/* T99W175 (sdx55), Both for eSIM and Non-eSIM */760	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0ab),761		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w175_info },762	/* DW5930e (sdx55), With eSIM, It's also T99W175 */763	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0b0),764		.driver_data = (kernel_ulong_t) &mhi_foxconn_dw5930e_info },765	/* DW5930e (sdx55), Non-eSIM, It's also T99W175 */766	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0b1),767		.driver_data = (kernel_ulong_t) &mhi_foxconn_dw5930e_info },768	/* T99W175 (sdx55), Based on Qualcomm new baseline */769	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0bf),770		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w175_info },771	/* T99W175 (sdx55) */772	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0c3),773		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w175_info },774	/* T99W368 (sdx65) */775	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d8),776		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w368_info },777	/* T99W373 (sdx62) */778	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d9),779		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w373_info },780	/* T99W510 (sdx24), variant 1 */781	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f0),782		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w510_info },783	/* T99W510 (sdx24), variant 2 */784	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f1),785		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w510_info },786	/* T99W510 (sdx24), variant 3 */787	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f2),788		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w510_info },789	/* DW5932e-eSIM (sdx62), With eSIM */790	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f5),791		.driver_data = (kernel_ulong_t) &mhi_foxconn_dw5932e_info },792	/* DW5932e (sdx62), Non-eSIM */793	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f9),794		.driver_data = (kernel_ulong_t) &mhi_foxconn_dw5932e_info },795	/* T99W515 (sdx72) */796	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe118),797		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w515_info },798	/* DW5934e(sdx72), With eSIM */799	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe11d),800		.driver_data = (kernel_ulong_t) &mhi_foxconn_dw5934e_info },801	/* DW5934e(sdx72), Non-eSIM */802	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe11e),803		.driver_data = (kernel_ulong_t) &mhi_foxconn_dw5934e_info },804	/* MV31-W (Cinterion) */805	{ PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3),806		.driver_data = (kernel_ulong_t) &mhi_mv31_info },807	/* MV31-W (Cinterion), based on new baseline */808	{ PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b4),809		.driver_data = (kernel_ulong_t) &mhi_mv31_info },810	/* MV32-WA (Cinterion) */811	{ PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00ba),812		.driver_data = (kernel_ulong_t) &mhi_mv32_info },813	/* MV32-WB (Cinterion) */814	{ PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00bb),815		.driver_data = (kernel_ulong_t) &mhi_mv32_info },816	/* T99W175 (sdx55), HP variant */817	{ PCI_DEVICE(0x03f0, 0x0a6c),818		.driver_data = (kernel_ulong_t) &mhi_foxconn_t99w175_info },819	/* NETPRISMA LCUR57 (SDX24) */820	{ PCI_DEVICE(PCI_VENDOR_ID_NETPRISMA, 0x1000),821		.driver_data = (kernel_ulong_t) &mhi_netprisma_lcur57_info },822	/* NETPRISMA FCUN69 (SDX6X) */823	{ PCI_DEVICE(PCI_VENDOR_ID_NETPRISMA, 0x1001),824		.driver_data = (kernel_ulong_t) &mhi_netprisma_fcun69_info },825	{  }826};827MODULE_DEVICE_TABLE(pci, mhi_pci_id_table);828 829enum mhi_pci_device_status {830	MHI_PCI_DEV_STARTED,831	MHI_PCI_DEV_SUSPENDED,832};833 834struct mhi_pci_device {835	struct mhi_controller mhi_cntrl;836	struct pci_saved_state *pci_state;837	struct work_struct recovery_work;838	struct timer_list health_check_timer;839	unsigned long status;840};841 842static int mhi_pci_read_reg(struct mhi_controller *mhi_cntrl,843			    void __iomem *addr, u32 *out)844{845	*out = readl(addr);846	return 0;847}848 849static void mhi_pci_write_reg(struct mhi_controller *mhi_cntrl,850			      void __iomem *addr, u32 val)851{852	writel(val, addr);853}854 855static void mhi_pci_status_cb(struct mhi_controller *mhi_cntrl,856			      enum mhi_callback cb)857{858	struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);859 860	/* Nothing to do for now */861	switch (cb) {862	case MHI_CB_FATAL_ERROR:863	case MHI_CB_SYS_ERROR:864		dev_warn(&pdev->dev, "firmware crashed (%u)\n", cb);865		pm_runtime_forbid(&pdev->dev);866		break;867	case MHI_CB_EE_MISSION_MODE:868		pm_runtime_allow(&pdev->dev);869		break;870	default:871		break;872	}873}874 875static void mhi_pci_wake_get_nop(struct mhi_controller *mhi_cntrl, bool force)876{877	/* no-op */878}879 880static void mhi_pci_wake_put_nop(struct mhi_controller *mhi_cntrl, bool override)881{882	/* no-op */883}884 885static void mhi_pci_wake_toggle_nop(struct mhi_controller *mhi_cntrl)886{887	/* no-op */888}889 890static bool mhi_pci_is_alive(struct mhi_controller *mhi_cntrl)891{892	struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);893	u16 vendor = 0;894 895	if (pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor))896		return false;897 898	if (vendor == (u16) ~0 || vendor == 0)899		return false;900 901	return true;902}903 904static int mhi_pci_claim(struct mhi_controller *mhi_cntrl,905			 unsigned int bar_num, u64 dma_mask)906{907	struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);908	int err;909 910	err = pci_assign_resource(pdev, bar_num);911	if (err)912		return err;913 914	err = pcim_enable_device(pdev);915	if (err) {916		dev_err(&pdev->dev, "failed to enable pci device: %d\n", err);917		return err;918	}919 920	err = pcim_iomap_regions(pdev, 1 << bar_num, pci_name(pdev));921	if (err) {922		dev_err(&pdev->dev, "failed to map pci region: %d\n", err);923		return err;924	}925	mhi_cntrl->regs = pcim_iomap_table(pdev)[bar_num];926	mhi_cntrl->reg_len = pci_resource_len(pdev, bar_num);927 928	err = dma_set_mask_and_coherent(&pdev->dev, dma_mask);929	if (err) {930		dev_err(&pdev->dev, "Cannot set proper DMA mask\n");931		return err;932	}933 934	pci_set_master(pdev);935 936	return 0;937}938 939static int mhi_pci_get_irqs(struct mhi_controller *mhi_cntrl,940			    const struct mhi_controller_config *mhi_cntrl_config)941{942	struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);943	int nr_vectors, i;944	int *irq;945 946	/*947	 * Alloc one MSI vector for BHI + one vector per event ring, ideally...948	 * No explicit pci_free_irq_vectors required, done by pcim_release.949	 */950	mhi_cntrl->nr_irqs = 1 + mhi_cntrl_config->num_events;951 952	nr_vectors = pci_alloc_irq_vectors(pdev, 1, mhi_cntrl->nr_irqs, PCI_IRQ_MSI);953	if (nr_vectors < 0) {954		dev_err(&pdev->dev, "Error allocating MSI vectors %d\n",955			nr_vectors);956		return nr_vectors;957	}958 959	if (nr_vectors < mhi_cntrl->nr_irqs) {960		dev_warn(&pdev->dev, "using shared MSI\n");961 962		/* Patch msi vectors, use only one (shared) */963		for (i = 0; i < mhi_cntrl_config->num_events; i++)964			mhi_cntrl_config->event_cfg[i].irq = 0;965		mhi_cntrl->nr_irqs = 1;966	}967 968	irq = devm_kcalloc(&pdev->dev, mhi_cntrl->nr_irqs, sizeof(int), GFP_KERNEL);969	if (!irq)970		return -ENOMEM;971 972	for (i = 0; i < mhi_cntrl->nr_irqs; i++) {973		int vector = i >= nr_vectors ? (nr_vectors - 1) : i;974 975		irq[i] = pci_irq_vector(pdev, vector);976	}977 978	mhi_cntrl->irq = irq;979 980	return 0;981}982 983static int mhi_pci_runtime_get(struct mhi_controller *mhi_cntrl)984{985	/* The runtime_get() MHI callback means:986	 *    Do whatever is requested to leave M3.987	 */988	return pm_runtime_get(mhi_cntrl->cntrl_dev);989}990 991static void mhi_pci_runtime_put(struct mhi_controller *mhi_cntrl)992{993	/* The runtime_put() MHI callback means:994	 *    Device can be moved in M3 state.995	 */996	pm_runtime_mark_last_busy(mhi_cntrl->cntrl_dev);997	pm_runtime_put(mhi_cntrl->cntrl_dev);998}999 1000static void mhi_pci_recovery_work(struct work_struct *work)1001{1002	struct mhi_pci_device *mhi_pdev = container_of(work, struct mhi_pci_device,1003						       recovery_work);1004	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1005	struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);1006	int err;1007 1008	dev_warn(&pdev->dev, "device recovery started\n");1009 1010	del_timer(&mhi_pdev->health_check_timer);1011	pm_runtime_forbid(&pdev->dev);1012 1013	/* Clean up MHI state */1014	if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {1015		mhi_power_down(mhi_cntrl, false);1016		mhi_unprepare_after_power_down(mhi_cntrl);1017	}1018 1019	pci_set_power_state(pdev, PCI_D0);1020	pci_load_saved_state(pdev, mhi_pdev->pci_state);1021	pci_restore_state(pdev);1022 1023	if (!mhi_pci_is_alive(mhi_cntrl))1024		goto err_try_reset;1025 1026	err = mhi_prepare_for_power_up(mhi_cntrl);1027	if (err)1028		goto err_try_reset;1029 1030	err = mhi_sync_power_up(mhi_cntrl);1031	if (err)1032		goto err_unprepare;1033 1034	dev_dbg(&pdev->dev, "Recovery completed\n");1035 1036	set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);1037	mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);1038	return;1039 1040err_unprepare:1041	mhi_unprepare_after_power_down(mhi_cntrl);1042err_try_reset:1043	if (pci_reset_function(pdev))1044		dev_err(&pdev->dev, "Recovery failed\n");1045}1046 1047static void health_check(struct timer_list *t)1048{1049	struct mhi_pci_device *mhi_pdev = from_timer(mhi_pdev, t, health_check_timer);1050	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1051 1052	if (!test_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status) ||1053			test_bit(MHI_PCI_DEV_SUSPENDED, &mhi_pdev->status))1054		return;1055 1056	if (!mhi_pci_is_alive(mhi_cntrl)) {1057		dev_err(mhi_cntrl->cntrl_dev, "Device died\n");1058		queue_work(system_long_wq, &mhi_pdev->recovery_work);1059		return;1060	}1061 1062	/* reschedule in two seconds */1063	mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);1064}1065 1066static int mhi_pci_generic_edl_trigger(struct mhi_controller *mhi_cntrl)1067{1068	void __iomem *base = mhi_cntrl->regs;1069	void __iomem *edl_db;1070	int ret;1071	u32 val;1072 1073	ret = mhi_device_get_sync(mhi_cntrl->mhi_dev);1074	if (ret) {1075		dev_err(mhi_cntrl->cntrl_dev, "Failed to wakeup the device\n");1076		return ret;1077	}1078 1079	pm_wakeup_event(&mhi_cntrl->mhi_dev->dev, 0);1080	mhi_cntrl->runtime_get(mhi_cntrl);1081 1082	ret = mhi_get_channel_doorbell_offset(mhi_cntrl, &val);1083	if (ret)1084		goto err_get_chdb;1085 1086	edl_db = base + val + (8 * MHI_EDL_DB);1087 1088	mhi_cntrl->write_reg(mhi_cntrl, edl_db + 4, upper_32_bits(MHI_EDL_COOKIE));1089	mhi_cntrl->write_reg(mhi_cntrl, edl_db, lower_32_bits(MHI_EDL_COOKIE));1090 1091	mhi_soc_reset(mhi_cntrl);1092 1093err_get_chdb:1094	mhi_cntrl->runtime_put(mhi_cntrl);1095	mhi_device_put(mhi_cntrl->mhi_dev);1096 1097	return ret;1098}1099 1100static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)1101{1102	const struct mhi_pci_dev_info *info = (struct mhi_pci_dev_info *) id->driver_data;1103	const struct mhi_controller_config *mhi_cntrl_config;1104	struct mhi_pci_device *mhi_pdev;1105	struct mhi_controller *mhi_cntrl;1106	int err;1107 1108	dev_info(&pdev->dev, "MHI PCI device found: %s\n", info->name);1109 1110	/* mhi_pdev.mhi_cntrl must be zero-initialized */1111	mhi_pdev = devm_kzalloc(&pdev->dev, sizeof(*mhi_pdev), GFP_KERNEL);1112	if (!mhi_pdev)1113		return -ENOMEM;1114 1115	INIT_WORK(&mhi_pdev->recovery_work, mhi_pci_recovery_work);1116	timer_setup(&mhi_pdev->health_check_timer, health_check, 0);1117 1118	mhi_cntrl_config = info->config;1119	mhi_cntrl = &mhi_pdev->mhi_cntrl;1120 1121	mhi_cntrl->cntrl_dev = &pdev->dev;1122	mhi_cntrl->iova_start = 0;1123	mhi_cntrl->iova_stop = (dma_addr_t)DMA_BIT_MASK(info->dma_data_width);1124	mhi_cntrl->fw_image = info->fw;1125	mhi_cntrl->edl_image = info->edl;1126 1127	mhi_cntrl->read_reg = mhi_pci_read_reg;1128	mhi_cntrl->write_reg = mhi_pci_write_reg;1129	mhi_cntrl->status_cb = mhi_pci_status_cb;1130	mhi_cntrl->runtime_get = mhi_pci_runtime_get;1131	mhi_cntrl->runtime_put = mhi_pci_runtime_put;1132	mhi_cntrl->mru = info->mru_default;1133	mhi_cntrl->name = info->name;1134 1135	if (info->edl_trigger)1136		mhi_cntrl->edl_trigger = mhi_pci_generic_edl_trigger;1137 1138	if (info->sideband_wake) {1139		mhi_cntrl->wake_get = mhi_pci_wake_get_nop;1140		mhi_cntrl->wake_put = mhi_pci_wake_put_nop;1141		mhi_cntrl->wake_toggle = mhi_pci_wake_toggle_nop;1142	}1143 1144	err = mhi_pci_claim(mhi_cntrl, info->bar_num, DMA_BIT_MASK(info->dma_data_width));1145	if (err)1146		return err;1147 1148	err = mhi_pci_get_irqs(mhi_cntrl, mhi_cntrl_config);1149	if (err)1150		return err;1151 1152	pci_set_drvdata(pdev, mhi_pdev);1153 1154	/* Have stored pci confspace at hand for restore in sudden PCI error.1155	 * cache the state locally and discard the PCI core one.1156	 */1157	pci_save_state(pdev);1158	mhi_pdev->pci_state = pci_store_saved_state(pdev);1159	pci_load_saved_state(pdev, NULL);1160 1161	err = mhi_register_controller(mhi_cntrl, mhi_cntrl_config);1162	if (err)1163		return err;1164 1165	/* MHI bus does not power up the controller by default */1166	err = mhi_prepare_for_power_up(mhi_cntrl);1167	if (err) {1168		dev_err(&pdev->dev, "failed to prepare MHI controller\n");1169		goto err_unregister;1170	}1171 1172	err = mhi_sync_power_up(mhi_cntrl);1173	if (err) {1174		dev_err(&pdev->dev, "failed to power up MHI controller\n");1175		goto err_unprepare;1176	}1177 1178	set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);1179 1180	/* start health check */1181	mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);1182 1183	/* Only allow runtime-suspend if PME capable (for wakeup) */1184	if (pci_pme_capable(pdev, PCI_D3hot)) {1185		pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);1186		pm_runtime_use_autosuspend(&pdev->dev);1187		pm_runtime_mark_last_busy(&pdev->dev);1188		pm_runtime_put_noidle(&pdev->dev);1189	}1190 1191	return 0;1192 1193err_unprepare:1194	mhi_unprepare_after_power_down(mhi_cntrl);1195err_unregister:1196	mhi_unregister_controller(mhi_cntrl);1197 1198	return err;1199}1200 1201static void mhi_pci_remove(struct pci_dev *pdev)1202{1203	struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);1204	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1205 1206	del_timer_sync(&mhi_pdev->health_check_timer);1207	cancel_work_sync(&mhi_pdev->recovery_work);1208 1209	if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {1210		mhi_power_down(mhi_cntrl, true);1211		mhi_unprepare_after_power_down(mhi_cntrl);1212	}1213 1214	/* balancing probe put_noidle */1215	if (pci_pme_capable(pdev, PCI_D3hot))1216		pm_runtime_get_noresume(&pdev->dev);1217 1218	mhi_unregister_controller(mhi_cntrl);1219}1220 1221static void mhi_pci_shutdown(struct pci_dev *pdev)1222{1223	mhi_pci_remove(pdev);1224	pci_set_power_state(pdev, PCI_D3hot);1225}1226 1227static void mhi_pci_reset_prepare(struct pci_dev *pdev)1228{1229	struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);1230	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1231 1232	dev_info(&pdev->dev, "reset\n");1233 1234	del_timer(&mhi_pdev->health_check_timer);1235 1236	/* Clean up MHI state */1237	if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {1238		mhi_power_down(mhi_cntrl, false);1239		mhi_unprepare_after_power_down(mhi_cntrl);1240	}1241 1242	/* cause internal device reset */1243	mhi_soc_reset(mhi_cntrl);1244 1245	/* Be sure device reset has been executed */1246	msleep(MHI_POST_RESET_DELAY_MS);1247}1248 1249static void mhi_pci_reset_done(struct pci_dev *pdev)1250{1251	struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);1252	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1253	int err;1254 1255	/* Restore initial known working PCI state */1256	pci_load_saved_state(pdev, mhi_pdev->pci_state);1257	pci_restore_state(pdev);1258 1259	/* Is device status available ? */1260	if (!mhi_pci_is_alive(mhi_cntrl)) {1261		dev_err(&pdev->dev, "reset failed\n");1262		return;1263	}1264 1265	err = mhi_prepare_for_power_up(mhi_cntrl);1266	if (err) {1267		dev_err(&pdev->dev, "failed to prepare MHI controller\n");1268		return;1269	}1270 1271	err = mhi_sync_power_up(mhi_cntrl);1272	if (err) {1273		dev_err(&pdev->dev, "failed to power up MHI controller\n");1274		mhi_unprepare_after_power_down(mhi_cntrl);1275		return;1276	}1277 1278	set_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status);1279	mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);1280}1281 1282static pci_ers_result_t mhi_pci_error_detected(struct pci_dev *pdev,1283					       pci_channel_state_t state)1284{1285	struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);1286	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1287 1288	dev_err(&pdev->dev, "PCI error detected, state = %u\n", state);1289 1290	if (state == pci_channel_io_perm_failure)1291		return PCI_ERS_RESULT_DISCONNECT;1292 1293	/* Clean up MHI state */1294	if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {1295		mhi_power_down(mhi_cntrl, false);1296		mhi_unprepare_after_power_down(mhi_cntrl);1297	} else {1298		/* Nothing to do */1299		return PCI_ERS_RESULT_RECOVERED;1300	}1301 1302	pci_disable_device(pdev);1303 1304	return PCI_ERS_RESULT_NEED_RESET;1305}1306 1307static pci_ers_result_t mhi_pci_slot_reset(struct pci_dev *pdev)1308{1309	if (pci_enable_device(pdev)) {1310		dev_err(&pdev->dev, "Cannot re-enable PCI device after reset.\n");1311		return PCI_ERS_RESULT_DISCONNECT;1312	}1313 1314	return PCI_ERS_RESULT_RECOVERED;1315}1316 1317static void mhi_pci_io_resume(struct pci_dev *pdev)1318{1319	struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);1320 1321	dev_err(&pdev->dev, "PCI slot reset done\n");1322 1323	queue_work(system_long_wq, &mhi_pdev->recovery_work);1324}1325 1326static const struct pci_error_handlers mhi_pci_err_handler = {1327	.error_detected = mhi_pci_error_detected,1328	.slot_reset = mhi_pci_slot_reset,1329	.resume = mhi_pci_io_resume,1330	.reset_prepare = mhi_pci_reset_prepare,1331	.reset_done = mhi_pci_reset_done,1332};1333 1334static int  __maybe_unused mhi_pci_runtime_suspend(struct device *dev)1335{1336	struct pci_dev *pdev = to_pci_dev(dev);1337	struct mhi_pci_device *mhi_pdev = dev_get_drvdata(dev);1338	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1339	int err;1340 1341	if (test_and_set_bit(MHI_PCI_DEV_SUSPENDED, &mhi_pdev->status))1342		return 0;1343 1344	del_timer(&mhi_pdev->health_check_timer);1345	cancel_work_sync(&mhi_pdev->recovery_work);1346 1347	if (!test_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status) ||1348			mhi_cntrl->ee != MHI_EE_AMSS)1349		goto pci_suspend; /* Nothing to do at MHI level */1350 1351	/* Transition to M3 state */1352	err = mhi_pm_suspend(mhi_cntrl);1353	if (err) {1354		dev_err(&pdev->dev, "failed to suspend device: %d\n", err);1355		clear_bit(MHI_PCI_DEV_SUSPENDED, &mhi_pdev->status);1356		return -EBUSY;1357	}1358 1359pci_suspend:1360	pci_disable_device(pdev);1361	pci_wake_from_d3(pdev, true);1362 1363	return 0;1364}1365 1366static int __maybe_unused mhi_pci_runtime_resume(struct device *dev)1367{1368	struct pci_dev *pdev = to_pci_dev(dev);1369	struct mhi_pci_device *mhi_pdev = dev_get_drvdata(dev);1370	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1371	int err;1372 1373	if (!test_and_clear_bit(MHI_PCI_DEV_SUSPENDED, &mhi_pdev->status))1374		return 0;1375 1376	err = pci_enable_device(pdev);1377	if (err)1378		goto err_recovery;1379 1380	pci_set_master(pdev);1381	pci_wake_from_d3(pdev, false);1382 1383	if (!test_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status) ||1384			mhi_cntrl->ee != MHI_EE_AMSS)1385		return 0; /* Nothing to do at MHI level */1386 1387	/* Exit M3, transition to M0 state */1388	err = mhi_pm_resume(mhi_cntrl);1389	if (err) {1390		dev_err(&pdev->dev, "failed to resume device: %d\n", err);1391		goto err_recovery;1392	}1393 1394	/* Resume health check */1395	mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD);1396 1397	/* It can be a remote wakeup (no mhi runtime_get), update access time */1398	pm_runtime_mark_last_busy(dev);1399 1400	return 0;1401 1402err_recovery:1403	/* Do not fail to not mess up our PCI device state, the device likely1404	 * lost power (d3cold) and we simply need to reset it from the recovery1405	 * procedure, trigger the recovery asynchronously to prevent system1406	 * suspend exit delaying.1407	 */1408	queue_work(system_long_wq, &mhi_pdev->recovery_work);1409	pm_runtime_mark_last_busy(dev);1410 1411	return 0;1412}1413 1414static int  __maybe_unused mhi_pci_suspend(struct device *dev)1415{1416	pm_runtime_disable(dev);1417	return mhi_pci_runtime_suspend(dev);1418}1419 1420static int __maybe_unused mhi_pci_resume(struct device *dev)1421{1422	int ret;1423 1424	/* Depending the platform, device may have lost power (d3cold), we need1425	 * to resume it now to check its state and recover when necessary.1426	 */1427	ret = mhi_pci_runtime_resume(dev);1428	pm_runtime_enable(dev);1429 1430	return ret;1431}1432 1433static int __maybe_unused mhi_pci_freeze(struct device *dev)1434{1435	struct mhi_pci_device *mhi_pdev = dev_get_drvdata(dev);1436	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;1437 1438	/* We want to stop all operations, hibernation does not guarantee that1439	 * device will be in the same state as before freezing, especially if1440	 * the intermediate restore kernel reinitializes MHI device with new1441	 * context.1442	 */1443	flush_work(&mhi_pdev->recovery_work);1444	if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {1445		mhi_power_down(mhi_cntrl, true);1446		mhi_unprepare_after_power_down(mhi_cntrl);1447	}1448 1449	return 0;1450}1451 1452static int __maybe_unused mhi_pci_restore(struct device *dev)1453{1454	struct mhi_pci_device *mhi_pdev = dev_get_drvdata(dev);1455 1456	/* Reinitialize the device */1457	queue_work(system_long_wq, &mhi_pdev->recovery_work);1458 1459	return 0;1460}1461 1462static const struct dev_pm_ops mhi_pci_pm_ops = {1463	SET_RUNTIME_PM_OPS(mhi_pci_runtime_suspend, mhi_pci_runtime_resume, NULL)1464#ifdef CONFIG_PM_SLEEP1465	.suspend = mhi_pci_suspend,1466	.resume = mhi_pci_resume,1467	.freeze = mhi_pci_freeze,1468	.thaw = mhi_pci_restore,1469	.poweroff = mhi_pci_freeze,1470	.restore = mhi_pci_restore,1471#endif1472};1473 1474static struct pci_driver mhi_pci_driver = {1475	.name		= "mhi-pci-generic",1476	.id_table	= mhi_pci_id_table,1477	.probe		= mhi_pci_probe,1478	.remove		= mhi_pci_remove,1479	.shutdown	= mhi_pci_shutdown,1480	.err_handler	= &mhi_pci_err_handler,1481	.driver.pm	= &mhi_pci_pm_ops1482};1483module_pci_driver(mhi_pci_driver);1484 1485MODULE_AUTHOR("Loic Poulain <loic.poulain@linaro.org>");1486MODULE_DESCRIPTION("Modem Host Interface (MHI) PCI controller driver");1487MODULE_LICENSE("GPL");1488