162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci *
362306a36Sopenharmony_ci * Copyright (C) 2020-21 Intel Corporation.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef IOSM_IPC_PCIE_H
762306a36Sopenharmony_ci#define IOSM_IPC_PCIE_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/device.h>
1062306a36Sopenharmony_ci#include <linux/pci.h>
1162306a36Sopenharmony_ci#include <linux/skbuff.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include "iosm_ipc_irq.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/* Device ID */
1662306a36Sopenharmony_ci#define INTEL_CP_DEVICE_7560_ID 0x7560
1762306a36Sopenharmony_ci#define INTEL_CP_DEVICE_7360_ID 0x7360
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/* Define for BAR area usage */
2062306a36Sopenharmony_ci#define IPC_DOORBELL_BAR0 0
2162306a36Sopenharmony_ci#define IPC_SCRATCHPAD_BAR2 2
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/* Defines for DOORBELL registers information */
2462306a36Sopenharmony_ci#define IPC_DOORBELL_CH_OFFSET BIT(5)
2562306a36Sopenharmony_ci#define IPC_WRITE_PTR_REG_0 BIT(4)
2662306a36Sopenharmony_ci#define IPC_CAPTURE_PTR_REG_0 BIT(3)
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* Number of MSI used for IPC */
2962306a36Sopenharmony_ci#define IPC_MSI_VECTORS 1
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/* Total number of Maximum IPC IRQ vectors used for IPC */
3262306a36Sopenharmony_ci#define IPC_IRQ_VECTORS IPC_MSI_VECTORS
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/**
3562306a36Sopenharmony_ci * enum ipc_pcie_sleep_state - Enum type to different sleep state transitions
3662306a36Sopenharmony_ci * @IPC_PCIE_D0L12:	Put the sleep state in D0L12
3762306a36Sopenharmony_ci * @IPC_PCIE_D3L2:	Put the sleep state in D3L2
3862306a36Sopenharmony_ci */
3962306a36Sopenharmony_cienum ipc_pcie_sleep_state {
4062306a36Sopenharmony_ci	IPC_PCIE_D0L12,
4162306a36Sopenharmony_ci	IPC_PCIE_D3L2,
4262306a36Sopenharmony_ci};
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/**
4562306a36Sopenharmony_ci * struct iosm_pcie - IPC_PCIE struct.
4662306a36Sopenharmony_ci * @pci:			Address of the device description
4762306a36Sopenharmony_ci * @dev:			Pointer to generic device structure
4862306a36Sopenharmony_ci * @ipc_regs:			Remapped CP doorbell address of the irq register
4962306a36Sopenharmony_ci *				set, to fire the doorbell irq.
5062306a36Sopenharmony_ci * @scratchpad:			Remapped CP scratchpad address, to send the
5162306a36Sopenharmony_ci *				configuration. tuple and the IPC descriptors
5262306a36Sopenharmony_ci *				to CP in the ROM phase. The config tuple
5362306a36Sopenharmony_ci *				information are saved on the MSI scratchpad.
5462306a36Sopenharmony_ci * @imem:			Pointer to imem data struct
5562306a36Sopenharmony_ci * @ipc_regs_bar_nr:		BAR number to be used for IPC doorbell
5662306a36Sopenharmony_ci * @scratchpad_bar_nr:		BAR number to be used for Scratchpad
5762306a36Sopenharmony_ci * @nvec:			number of requested irq vectors
5862306a36Sopenharmony_ci * @doorbell_reg_offset:	doorbell_reg_offset
5962306a36Sopenharmony_ci * @doorbell_write:		doorbell write register
6062306a36Sopenharmony_ci * @doorbell_capture:		doorbell capture resgister
6162306a36Sopenharmony_ci * @suspend:			S2IDLE sleep/active
6262306a36Sopenharmony_ci * @d3l2_support:		Read WWAN RTD3 BIOS setting for D3L2 support
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_cistruct iosm_pcie {
6562306a36Sopenharmony_ci	struct pci_dev *pci;
6662306a36Sopenharmony_ci	struct device *dev;
6762306a36Sopenharmony_ci	void __iomem *ipc_regs;
6862306a36Sopenharmony_ci	void __iomem *scratchpad;
6962306a36Sopenharmony_ci	struct iosm_imem *imem;
7062306a36Sopenharmony_ci	int ipc_regs_bar_nr;
7162306a36Sopenharmony_ci	int scratchpad_bar_nr;
7262306a36Sopenharmony_ci	int nvec;
7362306a36Sopenharmony_ci	u32 doorbell_reg_offset;
7462306a36Sopenharmony_ci	u32 doorbell_write;
7562306a36Sopenharmony_ci	u32 doorbell_capture;
7662306a36Sopenharmony_ci	unsigned long suspend;
7762306a36Sopenharmony_ci	enum ipc_pcie_sleep_state d3l2_support;
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/**
8162306a36Sopenharmony_ci * struct ipc_skb_cb - Struct definition of the socket buffer which is mapped to
8262306a36Sopenharmony_ci *		       the cb field of sbk
8362306a36Sopenharmony_ci * @mapping:	Store physical or IOVA mapped address of skb virtual add.
8462306a36Sopenharmony_ci * @direction:	DMA direction
8562306a36Sopenharmony_ci * @len:	Length of the DMA mapped region
8662306a36Sopenharmony_ci * @op_type:    Expected values are defined about enum ipc_ul_usr_op.
8762306a36Sopenharmony_ci */
8862306a36Sopenharmony_cistruct ipc_skb_cb {
8962306a36Sopenharmony_ci	dma_addr_t mapping;
9062306a36Sopenharmony_ci	int direction;
9162306a36Sopenharmony_ci	int len;
9262306a36Sopenharmony_ci	u8 op_type;
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/**
9662306a36Sopenharmony_ci * enum ipc_ul_usr_op - Control operation to execute the right action on
9762306a36Sopenharmony_ci *			the user interface.
9862306a36Sopenharmony_ci * @UL_USR_OP_BLOCKED:	The uplink app was blocked until CP confirms that the
9962306a36Sopenharmony_ci *			uplink buffer was consumed triggered by the IRQ.
10062306a36Sopenharmony_ci * @UL_MUX_OP_ADB:	In MUX mode the UL ADB shall be addedd to the free list.
10162306a36Sopenharmony_ci * @UL_DEFAULT:		SKB in non muxing mode
10262306a36Sopenharmony_ci */
10362306a36Sopenharmony_cienum ipc_ul_usr_op {
10462306a36Sopenharmony_ci	UL_USR_OP_BLOCKED,
10562306a36Sopenharmony_ci	UL_MUX_OP_ADB,
10662306a36Sopenharmony_ci	UL_DEFAULT,
10762306a36Sopenharmony_ci};
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/**
11062306a36Sopenharmony_ci * ipc_pcie_addr_map - Maps the kernel's virtual address to either IOVA
11162306a36Sopenharmony_ci *		       address space or Physical address space, the mapping is
11262306a36Sopenharmony_ci *		       stored in the skb's cb.
11362306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
11462306a36Sopenharmony_ci * @data:	Skb mem containing data
11562306a36Sopenharmony_ci * @size:	Data size
11662306a36Sopenharmony_ci * @mapping:	Dma mapping address
11762306a36Sopenharmony_ci * @direction:	Data direction
11862306a36Sopenharmony_ci *
11962306a36Sopenharmony_ci * Returns: 0 on success and failure value on error
12062306a36Sopenharmony_ci */
12162306a36Sopenharmony_ciint ipc_pcie_addr_map(struct iosm_pcie *ipc_pcie, unsigned char *data,
12262306a36Sopenharmony_ci		      size_t size, dma_addr_t *mapping, int direction);
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/**
12562306a36Sopenharmony_ci * ipc_pcie_addr_unmap - Unmaps the skb memory region from IOVA address space
12662306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
12762306a36Sopenharmony_ci * @size:	Data size
12862306a36Sopenharmony_ci * @mapping:	Dma mapping address
12962306a36Sopenharmony_ci * @direction:	Data direction
13062306a36Sopenharmony_ci */
13162306a36Sopenharmony_civoid ipc_pcie_addr_unmap(struct iosm_pcie *ipc_pcie, size_t size,
13262306a36Sopenharmony_ci			 dma_addr_t mapping, int direction);
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/**
13562306a36Sopenharmony_ci * ipc_pcie_alloc_skb - Allocate an uplink SKB for the given size.
13662306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
13762306a36Sopenharmony_ci * @size:	Size of the SKB required.
13862306a36Sopenharmony_ci * @flags:	Allocation flags
13962306a36Sopenharmony_ci * @mapping:	Copies either mapped IOVA add. or converted Phy address
14062306a36Sopenharmony_ci * @direction:	DMA data direction
14162306a36Sopenharmony_ci * @headroom:	Header data offset
14262306a36Sopenharmony_ci *
14362306a36Sopenharmony_ci * Returns: Pointer to ipc_skb on Success, NULL on failure.
14462306a36Sopenharmony_ci */
14562306a36Sopenharmony_cistruct sk_buff *ipc_pcie_alloc_skb(struct iosm_pcie *ipc_pcie, size_t size,
14662306a36Sopenharmony_ci				   gfp_t flags, dma_addr_t *mapping,
14762306a36Sopenharmony_ci				   int direction, size_t headroom);
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci/**
15062306a36Sopenharmony_ci * ipc_pcie_alloc_local_skb - Allocate a local SKB for the given size.
15162306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
15262306a36Sopenharmony_ci * @flags:	Allocation flags
15362306a36Sopenharmony_ci * @size:	Size of the SKB required.
15462306a36Sopenharmony_ci *
15562306a36Sopenharmony_ci * Returns: Pointer to ipc_skb on Success, NULL on failure.
15662306a36Sopenharmony_ci */
15762306a36Sopenharmony_cistruct sk_buff *ipc_pcie_alloc_local_skb(struct iosm_pcie *ipc_pcie,
15862306a36Sopenharmony_ci					 gfp_t flags, size_t size);
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci/**
16162306a36Sopenharmony_ci * ipc_pcie_kfree_skb - Free skb allocated by ipc_pcie_alloc_*_skb().
16262306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
16362306a36Sopenharmony_ci * @skb:	Pointer to the skb
16462306a36Sopenharmony_ci */
16562306a36Sopenharmony_civoid ipc_pcie_kfree_skb(struct iosm_pcie *ipc_pcie, struct sk_buff *skb);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci/**
16862306a36Sopenharmony_ci * ipc_pcie_check_data_link_active - Check Data Link Layer Active
16962306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
17062306a36Sopenharmony_ci *
17162306a36Sopenharmony_ci * Returns: true if active, otherwise false
17262306a36Sopenharmony_ci */
17362306a36Sopenharmony_cibool ipc_pcie_check_data_link_active(struct iosm_pcie *ipc_pcie);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/**
17662306a36Sopenharmony_ci * ipc_pcie_suspend - Callback invoked by pm_runtime_suspend. It decrements
17762306a36Sopenharmony_ci *		     the device's usage count then, carry out a suspend,
17862306a36Sopenharmony_ci *		     either synchronous or asynchronous.
17962306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
18062306a36Sopenharmony_ci *
18162306a36Sopenharmony_ci * Returns: 0 on success and failure value on error
18262306a36Sopenharmony_ci */
18362306a36Sopenharmony_ciint ipc_pcie_suspend(struct iosm_pcie *ipc_pcie);
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci/**
18662306a36Sopenharmony_ci * ipc_pcie_resume - Callback invoked by pm_runtime_resume. It increments
18762306a36Sopenharmony_ci *		    the device's usage count then, carry out a resume,
18862306a36Sopenharmony_ci *		    either synchronous or asynchronous.
18962306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
19062306a36Sopenharmony_ci *
19162306a36Sopenharmony_ci * Returns: 0 on success and failure value on error
19262306a36Sopenharmony_ci */
19362306a36Sopenharmony_ciint ipc_pcie_resume(struct iosm_pcie *ipc_pcie);
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci/**
19662306a36Sopenharmony_ci * ipc_pcie_check_aspm_enabled - Check if ASPM L1 is already enabled
19762306a36Sopenharmony_ci * @ipc_pcie:			 Pointer to struct iosm_pcie
19862306a36Sopenharmony_ci * @parent:			 True if checking ASPM L1 for parent else false
19962306a36Sopenharmony_ci *
20062306a36Sopenharmony_ci * Returns: true if ASPM is already enabled else false
20162306a36Sopenharmony_ci */
20262306a36Sopenharmony_cibool ipc_pcie_check_aspm_enabled(struct iosm_pcie *ipc_pcie,
20362306a36Sopenharmony_ci				 bool parent);
20462306a36Sopenharmony_ci/**
20562306a36Sopenharmony_ci * ipc_pcie_config_aspm - Configure ASPM L1
20662306a36Sopenharmony_ci * @ipc_pcie:	Pointer to struct iosm_pcie
20762306a36Sopenharmony_ci */
20862306a36Sopenharmony_civoid ipc_pcie_config_aspm(struct iosm_pcie *ipc_pcie);
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci#endif
211