xref: /openbmc/linux/include/linux/alcor_pci.h (revision 8efc5274)
14f556bc0SOleksij Rempel /* SPDX-License-Identifier: GPL-2.0+ */
24f556bc0SOleksij Rempel /*
34f556bc0SOleksij Rempel  * Copyright (C) 2018 Oleksij Rempel <linux@rempel-privat.de>
44f556bc0SOleksij Rempel  *
54f556bc0SOleksij Rempel  * Driver for Alcor Micro AU6601 and AU6621 controllers
64f556bc0SOleksij Rempel  */
74f556bc0SOleksij Rempel 
84f556bc0SOleksij Rempel #ifndef __ALCOR_PCI_H
94f556bc0SOleksij Rempel #define __ALCOR_PCI_H
104f556bc0SOleksij Rempel 
114f556bc0SOleksij Rempel #define ALCOR_SD_CARD 0
124f556bc0SOleksij Rempel #define ALCOR_MS_CARD 1
134f556bc0SOleksij Rempel 
144f556bc0SOleksij Rempel #define DRV_NAME_ALCOR_PCI_SDMMC		"alcor_sdmmc"
154f556bc0SOleksij Rempel #define DRV_NAME_ALCOR_PCI_MS			"alcor_ms"
164f556bc0SOleksij Rempel 
174f556bc0SOleksij Rempel #define PCI_ID_ALCOR_MICRO			0x1AEA
184f556bc0SOleksij Rempel #define PCI_ID_AU6601				0x6601
194f556bc0SOleksij Rempel #define PCI_ID_AU6621				0x6621
20444972b2SRhys Perry #define PCI_ID_AU6625				0x6625
214f556bc0SOleksij Rempel 
224f556bc0SOleksij Rempel #define MHZ_TO_HZ(freq)				((freq) * 1000 * 1000)
234f556bc0SOleksij Rempel 
244f556bc0SOleksij Rempel #define AU6601_BASE_CLOCK			31000000
254f556bc0SOleksij Rempel #define AU6601_MIN_CLOCK			150000
264f556bc0SOleksij Rempel #define AU6601_MAX_CLOCK			208000000
27c671b6deSDaniel Drake #define AU6601_MAX_DMA_SEGMENTS			64
284f556bc0SOleksij Rempel #define AU6601_MAX_PIO_SEGMENTS			1
294f556bc0SOleksij Rempel #define AU6601_MAX_DMA_BLOCK_SIZE		0x1000
304f556bc0SOleksij Rempel #define AU6601_MAX_PIO_BLOCK_SIZE		0x200
314f556bc0SOleksij Rempel #define AU6601_MAX_DMA_BLOCKS			1
324f556bc0SOleksij Rempel #define AU6601_DMA_LOCAL_SEGMENTS		1
334f556bc0SOleksij Rempel 
344f556bc0SOleksij Rempel /* registers spotter by reverse engineering but still
354f556bc0SOleksij Rempel  * with unknown functionality:
364f556bc0SOleksij Rempel  * 0x10 - ADMA phy address. AU6621 only?
374f556bc0SOleksij Rempel  * 0x51 - LED ctrl?
384f556bc0SOleksij Rempel  * 0x52 - unknown
394f556bc0SOleksij Rempel  * 0x61 - LED related? Always toggled BIT0
404f556bc0SOleksij Rempel  * 0x63 - Same as 0x61?
414f556bc0SOleksij Rempel  * 0x77 - unknown
424f556bc0SOleksij Rempel  */
434f556bc0SOleksij Rempel 
444f556bc0SOleksij Rempel /* SDMA phy address. Higher then 0x0800.0000?
454f556bc0SOleksij Rempel  * The au6601 and au6621 have different DMA engines with different issues. One
464f556bc0SOleksij Rempel  * For example au6621 engine is triggered by addr change. No other interaction
474f556bc0SOleksij Rempel  * is needed. This means, if we get two buffers with same address, then engine
484f556bc0SOleksij Rempel  * will stall.
494f556bc0SOleksij Rempel  */
504f556bc0SOleksij Rempel #define AU6601_REG_SDMA_ADDR			0x00
514f556bc0SOleksij Rempel #define AU6601_SDMA_MASK			0xffffffff
524f556bc0SOleksij Rempel 
534f556bc0SOleksij Rempel #define AU6601_DMA_BOUNDARY			0x05
544f556bc0SOleksij Rempel #define AU6621_DMA_PAGE_CNT			0x05
554f556bc0SOleksij Rempel /* PIO */
564f556bc0SOleksij Rempel #define AU6601_REG_BUFFER			0x08
574f556bc0SOleksij Rempel /* ADMA ctrl? AU6621 only. */
584f556bc0SOleksij Rempel #define AU6621_DMA_CTRL				0x0c
594f556bc0SOleksij Rempel #define AU6621_DMA_ENABLE			BIT(0)
604f556bc0SOleksij Rempel /* CMD index */
614f556bc0SOleksij Rempel #define AU6601_REG_CMD_OPCODE			0x23
624f556bc0SOleksij Rempel /* CMD parametr */
634f556bc0SOleksij Rempel #define AU6601_REG_CMD_ARG			0x24
644f556bc0SOleksij Rempel /* CMD response 4x4 Bytes */
654f556bc0SOleksij Rempel #define AU6601_REG_CMD_RSP0			0x30
664f556bc0SOleksij Rempel #define AU6601_REG_CMD_RSP1			0x34
674f556bc0SOleksij Rempel #define AU6601_REG_CMD_RSP2			0x38
684f556bc0SOleksij Rempel #define AU6601_REG_CMD_RSP3			0x3C
694f556bc0SOleksij Rempel /* default timeout set to 125: 125 * 40ms = 5 sec
704f556bc0SOleksij Rempel  * how exactly it is calculated?
714f556bc0SOleksij Rempel  */
724f556bc0SOleksij Rempel #define AU6601_TIME_OUT_CTRL			0x69
734f556bc0SOleksij Rempel /* Block size for SDMA or PIO */
744f556bc0SOleksij Rempel #define AU6601_REG_BLOCK_SIZE			0x6c
754f556bc0SOleksij Rempel /* Some power related reg, used together with AU6601_OUTPUT_ENABLE */
764f556bc0SOleksij Rempel #define AU6601_POWER_CONTROL			0x70
774f556bc0SOleksij Rempel 
784f556bc0SOleksij Rempel /* PLL ctrl */
794f556bc0SOleksij Rempel #define AU6601_CLK_SELECT			0x72
804f556bc0SOleksij Rempel #define	AU6601_CLK_OVER_CLK			0x80
814f556bc0SOleksij Rempel #define	AU6601_CLK_384_MHZ			0x30
824f556bc0SOleksij Rempel #define	AU6601_CLK_125_MHZ			0x20
834f556bc0SOleksij Rempel #define	AU6601_CLK_48_MHZ			0x10
844f556bc0SOleksij Rempel #define	AU6601_CLK_EXT_PLL			0x04
854f556bc0SOleksij Rempel #define AU6601_CLK_X2_MODE			0x02
864f556bc0SOleksij Rempel #define AU6601_CLK_ENABLE			0x01
874f556bc0SOleksij Rempel #define AU6601_CLK_31_25_MHZ			0x00
884f556bc0SOleksij Rempel 
894f556bc0SOleksij Rempel #define AU6601_CLK_DIVIDER			0x73
904f556bc0SOleksij Rempel 
914f556bc0SOleksij Rempel #define AU6601_INTERFACE_MODE_CTRL		0x74
924f556bc0SOleksij Rempel #define AU6601_DLINK_MODE			0x80
934f556bc0SOleksij Rempel #define	AU6601_INTERRUPT_DELAY_TIME		0x40
944f556bc0SOleksij Rempel #define	AU6601_SIGNAL_REQ_CTRL			0x30
954f556bc0SOleksij Rempel #define AU6601_MS_CARD_WP			BIT(3)
964f556bc0SOleksij Rempel #define AU6601_SD_CARD_WP			BIT(0)
974f556bc0SOleksij Rempel 
984f556bc0SOleksij Rempel /* same register values are used for:
994f556bc0SOleksij Rempel  *  - AU6601_OUTPUT_ENABLE
1004f556bc0SOleksij Rempel  *  - AU6601_POWER_CONTROL
1014f556bc0SOleksij Rempel  */
1024f556bc0SOleksij Rempel #define AU6601_ACTIVE_CTRL			0x75
1034f556bc0SOleksij Rempel #define AU6601_XD_CARD				BIT(4)
1044f556bc0SOleksij Rempel /* AU6601_MS_CARD_ACTIVE - will cativate MS card section? */
1054f556bc0SOleksij Rempel #define AU6601_MS_CARD				BIT(3)
1064f556bc0SOleksij Rempel #define AU6601_SD_CARD				BIT(0)
1074f556bc0SOleksij Rempel 
1084f556bc0SOleksij Rempel /* card slot state. It should automatically detect type of
1094f556bc0SOleksij Rempel  * the card
1104f556bc0SOleksij Rempel  */
1114f556bc0SOleksij Rempel #define AU6601_DETECT_STATUS			0x76
1124f556bc0SOleksij Rempel #define AU6601_DETECT_EN			BIT(7)
1134f556bc0SOleksij Rempel #define AU6601_MS_DETECTED			BIT(3)
1144f556bc0SOleksij Rempel #define AU6601_SD_DETECTED			BIT(0)
1154f556bc0SOleksij Rempel #define AU6601_DETECT_STATUS_M			0xf
1164f556bc0SOleksij Rempel 
1174f556bc0SOleksij Rempel #define AU6601_REG_SW_RESET			0x79
1184f556bc0SOleksij Rempel #define AU6601_BUF_CTRL_RESET			BIT(7)
1194f556bc0SOleksij Rempel #define AU6601_RESET_DATA			BIT(3)
1204f556bc0SOleksij Rempel #define AU6601_RESET_CMD			BIT(0)
1214f556bc0SOleksij Rempel 
1224f556bc0SOleksij Rempel #define AU6601_OUTPUT_ENABLE			0x7a
1234f556bc0SOleksij Rempel 
1244f556bc0SOleksij Rempel #define AU6601_PAD_DRIVE0			0x7b
1254f556bc0SOleksij Rempel #define AU6601_PAD_DRIVE1			0x7c
1264f556bc0SOleksij Rempel #define AU6601_PAD_DRIVE2			0x7d
1274f556bc0SOleksij Rempel /* read EEPROM? */
1284f556bc0SOleksij Rempel #define AU6601_FUNCTION				0x7f
1294f556bc0SOleksij Rempel 
1304f556bc0SOleksij Rempel #define AU6601_CMD_XFER_CTRL			0x81
1314f556bc0SOleksij Rempel #define	AU6601_CMD_17_BYTE_CRC			0xc0
1324f556bc0SOleksij Rempel #define	AU6601_CMD_6_BYTE_WO_CRC		0x80
1334f556bc0SOleksij Rempel #define	AU6601_CMD_6_BYTE_CRC			0x40
1344f556bc0SOleksij Rempel #define	AU6601_CMD_START_XFER			0x20
1354f556bc0SOleksij Rempel #define	AU6601_CMD_STOP_WAIT_RDY		0x10
1364f556bc0SOleksij Rempel #define	AU6601_CMD_NO_RESP			0x00
1374f556bc0SOleksij Rempel 
1384f556bc0SOleksij Rempel #define AU6601_REG_BUS_CTRL			0x82
1394f556bc0SOleksij Rempel #define AU6601_BUS_WIDTH_4BIT			0x20
1404f556bc0SOleksij Rempel #define AU6601_BUS_WIDTH_8BIT			0x10
1414f556bc0SOleksij Rempel #define AU6601_BUS_WIDTH_1BIT			0x00
1424f556bc0SOleksij Rempel 
1434f556bc0SOleksij Rempel #define AU6601_DATA_XFER_CTRL			0x83
1444f556bc0SOleksij Rempel #define AU6601_DATA_WRITE			BIT(7)
1454f556bc0SOleksij Rempel #define AU6601_DATA_DMA_MODE			BIT(6)
1464f556bc0SOleksij Rempel #define AU6601_DATA_START_XFER			BIT(0)
1474f556bc0SOleksij Rempel 
1484f556bc0SOleksij Rempel #define AU6601_DATA_PIN_STATE			0x84
1494f556bc0SOleksij Rempel #define AU6601_BUS_STAT_CMD			BIT(15)
1504f556bc0SOleksij Rempel /* BIT(4) - BIT(7) are permanently 1.
1514f556bc0SOleksij Rempel  * May be reserved or not attached DAT4-DAT7
1524f556bc0SOleksij Rempel  */
1534f556bc0SOleksij Rempel #define AU6601_BUS_STAT_DAT3			BIT(3)
1544f556bc0SOleksij Rempel #define AU6601_BUS_STAT_DAT2			BIT(2)
1554f556bc0SOleksij Rempel #define AU6601_BUS_STAT_DAT1			BIT(1)
1564f556bc0SOleksij Rempel #define AU6601_BUS_STAT_DAT0			BIT(0)
1574f556bc0SOleksij Rempel #define AU6601_BUS_STAT_DAT_MASK		0xf
1584f556bc0SOleksij Rempel 
1594f556bc0SOleksij Rempel #define AU6601_OPT				0x85
1604f556bc0SOleksij Rempel #define	AU6601_OPT_CMD_LINE_LEVEL		0x80
1614f556bc0SOleksij Rempel #define	AU6601_OPT_NCRC_16_CLK			BIT(4)
1624f556bc0SOleksij Rempel #define	AU6601_OPT_CMD_NWT			BIT(3)
1634f556bc0SOleksij Rempel #define	AU6601_OPT_STOP_CLK			BIT(2)
1644f556bc0SOleksij Rempel #define	AU6601_OPT_DDR_MODE			BIT(1)
1654f556bc0SOleksij Rempel #define	AU6601_OPT_SD_18V			BIT(0)
1664f556bc0SOleksij Rempel 
1674f556bc0SOleksij Rempel #define AU6601_CLK_DELAY			0x86
1684f556bc0SOleksij Rempel #define	AU6601_CLK_DATA_POSITIVE_EDGE		0x80
1694f556bc0SOleksij Rempel #define	AU6601_CLK_CMD_POSITIVE_EDGE		0x40
1704f556bc0SOleksij Rempel #define	AU6601_CLK_POSITIVE_EDGE_ALL		(AU6601_CLK_CMD_POSITIVE_EDGE \
1714f556bc0SOleksij Rempel 						| AU6601_CLK_DATA_POSITIVE_EDGE)
1724f556bc0SOleksij Rempel 
1734f556bc0SOleksij Rempel 
1744f556bc0SOleksij Rempel #define AU6601_REG_INT_STATUS			0x90
1754f556bc0SOleksij Rempel #define AU6601_REG_INT_ENABLE			0x94
1764f556bc0SOleksij Rempel #define AU6601_INT_DATA_END_BIT_ERR		BIT(22)
1774f556bc0SOleksij Rempel #define AU6601_INT_DATA_CRC_ERR			BIT(21)
1784f556bc0SOleksij Rempel #define AU6601_INT_DATA_TIMEOUT_ERR		BIT(20)
1794f556bc0SOleksij Rempel #define AU6601_INT_CMD_INDEX_ERR		BIT(19)
1804f556bc0SOleksij Rempel #define AU6601_INT_CMD_END_BIT_ERR		BIT(18)
1814f556bc0SOleksij Rempel #define AU6601_INT_CMD_CRC_ERR			BIT(17)
1824f556bc0SOleksij Rempel #define AU6601_INT_CMD_TIMEOUT_ERR		BIT(16)
1834f556bc0SOleksij Rempel #define AU6601_INT_ERROR			BIT(15)
1844f556bc0SOleksij Rempel #define AU6601_INT_OVER_CURRENT_ERR		BIT(8)
1854f556bc0SOleksij Rempel #define AU6601_INT_CARD_INSERT			BIT(7)
1864f556bc0SOleksij Rempel #define AU6601_INT_CARD_REMOVE			BIT(6)
1874f556bc0SOleksij Rempel #define AU6601_INT_READ_BUF_RDY			BIT(5)
1884f556bc0SOleksij Rempel #define AU6601_INT_WRITE_BUF_RDY		BIT(4)
1894f556bc0SOleksij Rempel #define AU6601_INT_DMA_END			BIT(3)
1904f556bc0SOleksij Rempel #define AU6601_INT_DATA_END			BIT(1)
1914f556bc0SOleksij Rempel #define AU6601_INT_CMD_END			BIT(0)
1924f556bc0SOleksij Rempel 
1934f556bc0SOleksij Rempel #define AU6601_INT_NORMAL_MASK			0x00007FFF
1944f556bc0SOleksij Rempel #define AU6601_INT_ERROR_MASK			0xFFFF8000
1954f556bc0SOleksij Rempel 
1964f556bc0SOleksij Rempel #define AU6601_INT_CMD_MASK	(AU6601_INT_CMD_END | \
1974f556bc0SOleksij Rempel 		AU6601_INT_CMD_TIMEOUT_ERR | AU6601_INT_CMD_CRC_ERR | \
1984f556bc0SOleksij Rempel 		AU6601_INT_CMD_END_BIT_ERR | AU6601_INT_CMD_INDEX_ERR)
1994f556bc0SOleksij Rempel #define AU6601_INT_DATA_MASK	(AU6601_INT_DATA_END | AU6601_INT_DMA_END | \
2004f556bc0SOleksij Rempel 		AU6601_INT_READ_BUF_RDY | AU6601_INT_WRITE_BUF_RDY | \
2014f556bc0SOleksij Rempel 		AU6601_INT_DATA_TIMEOUT_ERR | AU6601_INT_DATA_CRC_ERR | \
2024f556bc0SOleksij Rempel 		AU6601_INT_DATA_END_BIT_ERR)
2034f556bc0SOleksij Rempel #define AU6601_INT_ALL_MASK			((u32)-1)
2044f556bc0SOleksij Rempel 
2054f556bc0SOleksij Rempel /* MS_CARD mode registers */
2064f556bc0SOleksij Rempel 
2074f556bc0SOleksij Rempel #define AU6601_MS_STATUS			0xa0
2084f556bc0SOleksij Rempel 
2094f556bc0SOleksij Rempel #define AU6601_MS_BUS_MODE_CTRL			0xa1
2104f556bc0SOleksij Rempel #define AU6601_MS_BUS_8BIT_MODE			0x03
2114f556bc0SOleksij Rempel #define AU6601_MS_BUS_4BIT_MODE			0x01
2124f556bc0SOleksij Rempel #define AU6601_MS_BUS_1BIT_MODE			0x00
2134f556bc0SOleksij Rempel 
2144f556bc0SOleksij Rempel #define AU6601_MS_TPC_CMD			0xa2
2154f556bc0SOleksij Rempel #define AU6601_MS_TPC_READ_PAGE_DATA		0x02
2164f556bc0SOleksij Rempel #define AU6601_MS_TPC_READ_REG			0x04
2174f556bc0SOleksij Rempel #define AU6601_MS_TPC_GET_INT			0x07
2184f556bc0SOleksij Rempel #define AU6601_MS_TPC_WRITE_PAGE_DATA		0x0D
2194f556bc0SOleksij Rempel #define AU6601_MS_TPC_WRITE_REG			0x0B
2204f556bc0SOleksij Rempel #define AU6601_MS_TPC_SET_RW_REG_ADRS		0x08
2214f556bc0SOleksij Rempel #define AU6601_MS_TPC_SET_CMD			0x0E
2224f556bc0SOleksij Rempel #define AU6601_MS_TPC_EX_SET_CMD		0x09
2234f556bc0SOleksij Rempel #define AU6601_MS_TPC_READ_SHORT_DATA		0x03
2244f556bc0SOleksij Rempel #define AU6601_MS_TPC_WRITE_SHORT_DATA		0x0C
2254f556bc0SOleksij Rempel 
2264f556bc0SOleksij Rempel #define AU6601_MS_TRANSFER_MODE			0xa3
2274f556bc0SOleksij Rempel #define	AU6601_MS_XFER_INT_TIMEOUT_CHK		BIT(2)
2284f556bc0SOleksij Rempel #define	AU6601_MS_XFER_DMA_ENABLE		BIT(1)
2294f556bc0SOleksij Rempel #define	AU6601_MS_XFER_START			BIT(0)
2304f556bc0SOleksij Rempel 
2314f556bc0SOleksij Rempel #define AU6601_MS_DATA_PIN_STATE		0xa4
2324f556bc0SOleksij Rempel 
2334f556bc0SOleksij Rempel #define AU6601_MS_INT_STATUS			0xb0
2344f556bc0SOleksij Rempel #define AU6601_MS_INT_ENABLE			0xb4
2354f556bc0SOleksij Rempel #define AU6601_MS_INT_OVER_CURRENT_ERROR	BIT(23)
2364f556bc0SOleksij Rempel #define AU6601_MS_INT_DATA_CRC_ERROR		BIT(21)
2374f556bc0SOleksij Rempel #define AU6601_MS_INT_INT_TIMEOUT		BIT(20)
2384f556bc0SOleksij Rempel #define AU6601_MS_INT_INT_RESP_ERROR		BIT(19)
2394f556bc0SOleksij Rempel #define AU6601_MS_INT_CED_ERROR			BIT(18)
2404f556bc0SOleksij Rempel #define AU6601_MS_INT_TPC_TIMEOUT		BIT(16)
2414f556bc0SOleksij Rempel #define AU6601_MS_INT_ERROR			BIT(15)
2424f556bc0SOleksij Rempel #define AU6601_MS_INT_CARD_INSERT		BIT(7)
2434f556bc0SOleksij Rempel #define AU6601_MS_INT_CARD_REMOVE		BIT(6)
2444f556bc0SOleksij Rempel #define AU6601_MS_INT_BUF_READ_RDY		BIT(5)
2454f556bc0SOleksij Rempel #define AU6601_MS_INT_BUF_WRITE_RDY		BIT(4)
2464f556bc0SOleksij Rempel #define AU6601_MS_INT_DMA_END			BIT(3)
2474f556bc0SOleksij Rempel #define AU6601_MS_INT_TPC_END			BIT(1)
2484f556bc0SOleksij Rempel 
2494f556bc0SOleksij Rempel #define AU6601_MS_INT_DATA_MASK			0x00000038
2504f556bc0SOleksij Rempel #define AU6601_MS_INT_TPC_MASK			0x003d8002
2514f556bc0SOleksij Rempel #define AU6601_MS_INT_TPC_ERROR			0x003d0000
2524f556bc0SOleksij Rempel 
2534f556bc0SOleksij Rempel #define ALCOR_PCIE_LINK_CTRL_OFFSET		0x10
2544f556bc0SOleksij Rempel #define ALCOR_PCIE_LINK_CAP_OFFSET		0x0c
2554f556bc0SOleksij Rempel #define ALCOR_CAP_START_OFFSET			0x34
2564f556bc0SOleksij Rempel 
2574f556bc0SOleksij Rempel struct alcor_dev_cfg {
2584f556bc0SOleksij Rempel 	u8	dma;
2594f556bc0SOleksij Rempel };
2604f556bc0SOleksij Rempel 
2614f556bc0SOleksij Rempel struct alcor_pci_priv {
2624f556bc0SOleksij Rempel 	struct pci_dev *pdev;
2634f556bc0SOleksij Rempel 	struct pci_dev *parent_pdev;
2644f556bc0SOleksij Rempel 	struct  device *dev;
2654f556bc0SOleksij Rempel 	void __iomem *iobase;
2664f556bc0SOleksij Rempel 	unsigned int irq;
2674f556bc0SOleksij Rempel 
2684f556bc0SOleksij Rempel 	unsigned long id; /* idr id */
2694f556bc0SOleksij Rempel 
2704f556bc0SOleksij Rempel 	struct alcor_dev_cfg	*cfg;
2714f556bc0SOleksij Rempel };
2724f556bc0SOleksij Rempel 
2734f556bc0SOleksij Rempel void alcor_write8(struct alcor_pci_priv *priv, u8 val, unsigned int addr);
2744f556bc0SOleksij Rempel void alcor_write16(struct alcor_pci_priv *priv, u16 val, unsigned int addr);
2754f556bc0SOleksij Rempel void alcor_write32(struct alcor_pci_priv *priv, u32 val, unsigned int addr);
2764f556bc0SOleksij Rempel void alcor_write32be(struct alcor_pci_priv *priv, u32 val, unsigned int addr);
2774f556bc0SOleksij Rempel u8 alcor_read8(struct alcor_pci_priv *priv, unsigned int addr);
2784f556bc0SOleksij Rempel u32 alcor_read32(struct alcor_pci_priv *priv, unsigned int addr);
2794f556bc0SOleksij Rempel u32 alcor_read32be(struct alcor_pci_priv *priv, unsigned int addr);
2804f556bc0SOleksij Rempel #endif
281