1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park * Copyright (C) 2018 Marvell International Ltd.
3*54fd6939SJiyong Park *
4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park * https://spdx.org/licenses
6*54fd6939SJiyong Park */
7*54fd6939SJiyong Park
8*54fd6939SJiyong Park /* Marvell CP110 ana A3700 common */
9*54fd6939SJiyong Park
10*54fd6939SJiyong Park #ifndef PHY_COMPHY_COMMON_H
11*54fd6939SJiyong Park #define PHY_COMPHY_COMMON_H
12*54fd6939SJiyong Park
13*54fd6939SJiyong Park /* #define DEBUG_COMPHY */
14*54fd6939SJiyong Park #ifdef DEBUG_COMPHY
15*54fd6939SJiyong Park #define debug(format...) printf(format)
16*54fd6939SJiyong Park #else
17*54fd6939SJiyong Park #define debug(format, arg...)
18*54fd6939SJiyong Park #endif
19*54fd6939SJiyong Park
20*54fd6939SJiyong Park /* A lane is described by 4 fields:
21*54fd6939SJiyong Park * - bit 1~0 represent comphy polarity invert
22*54fd6939SJiyong Park * - bit 7~2 represent comphy speed
23*54fd6939SJiyong Park * - bit 11~8 represent unit index
24*54fd6939SJiyong Park * - bit 16~12 represent mode
25*54fd6939SJiyong Park * - bit 17 represent comphy indication of clock source
26*54fd6939SJiyong Park * - bit 20~18 represents pcie width (in case of pcie comphy config.)
27*54fd6939SJiyong Park * - bit 21 represents the source of the request (Linux/Bootloader),
28*54fd6939SJiyong Park * (reguired only for PCIe!)
29*54fd6939SJiyong Park * - bit 31~22 reserved
30*54fd6939SJiyong Park */
31*54fd6939SJiyong Park
32*54fd6939SJiyong Park #define COMPHY_INVERT_OFFSET 0
33*54fd6939SJiyong Park #define COMPHY_INVERT_LEN 2
34*54fd6939SJiyong Park #define COMPHY_INVERT_MASK COMPHY_MASK(COMPHY_INVERT_OFFSET, \
35*54fd6939SJiyong Park COMPHY_INVERT_LEN)
36*54fd6939SJiyong Park #define COMPHY_SPEED_OFFSET (COMPHY_INVERT_OFFSET + COMPHY_INVERT_LEN)
37*54fd6939SJiyong Park #define COMPHY_SPEED_LEN 6
38*54fd6939SJiyong Park #define COMPHY_SPEED_MASK COMPHY_MASK(COMPHY_SPEED_OFFSET, \
39*54fd6939SJiyong Park COMPHY_SPEED_LEN)
40*54fd6939SJiyong Park #define COMPHY_UNIT_ID_OFFSET (COMPHY_SPEED_OFFSET + COMPHY_SPEED_LEN)
41*54fd6939SJiyong Park #define COMPHY_UNIT_ID_LEN 4
42*54fd6939SJiyong Park #define COMPHY_UNIT_ID_MASK COMPHY_MASK(COMPHY_UNIT_ID_OFFSET, \
43*54fd6939SJiyong Park COMPHY_UNIT_ID_LEN)
44*54fd6939SJiyong Park #define COMPHY_MODE_OFFSET (COMPHY_UNIT_ID_OFFSET + COMPHY_UNIT_ID_LEN)
45*54fd6939SJiyong Park #define COMPHY_MODE_LEN 5
46*54fd6939SJiyong Park #define COMPHY_MODE_MASK COMPHY_MASK(COMPHY_MODE_OFFSET, COMPHY_MODE_LEN)
47*54fd6939SJiyong Park #define COMPHY_CLK_SRC_OFFSET (COMPHY_MODE_OFFSET + COMPHY_MODE_LEN)
48*54fd6939SJiyong Park #define COMPHY_CLK_SRC_LEN 1
49*54fd6939SJiyong Park #define COMPHY_CLK_SRC_MASK COMPHY_MASK(COMPHY_CLK_SRC_OFFSET, \
50*54fd6939SJiyong Park COMPHY_CLK_SRC_LEN)
51*54fd6939SJiyong Park #define COMPHY_PCI_WIDTH_OFFSET (COMPHY_CLK_SRC_OFFSET + COMPHY_CLK_SRC_LEN)
52*54fd6939SJiyong Park #define COMPHY_PCI_WIDTH_LEN 3
53*54fd6939SJiyong Park #define COMPHY_PCI_WIDTH_MASK COMPHY_MASK(COMPHY_PCI_WIDTH_OFFSET, \
54*54fd6939SJiyong Park COMPHY_PCI_WIDTH_LEN)
55*54fd6939SJiyong Park #define COMPHY_PCI_CALLER_OFFSET \
56*54fd6939SJiyong Park (COMPHY_PCI_WIDTH_OFFSET + COMPHY_PCI_WIDTH_LEN)
57*54fd6939SJiyong Park #define COMPHY_PCI_CALLER_LEN 1
58*54fd6939SJiyong Park #define COMPHY_PCI_CALLER_MASK COMPHY_MASK(COMPHY_PCI_CALLER_OFFSET, \
59*54fd6939SJiyong Park COMPHY_PCI_CALLER_LEN)
60*54fd6939SJiyong Park
61*54fd6939SJiyong Park #define COMPHY_MASK(offset, len) (((1 << (len)) - 1) << (offset))
62*54fd6939SJiyong Park
63*54fd6939SJiyong Park /* Macro which extracts mode from lane description */
64*54fd6939SJiyong Park #define COMPHY_GET_MODE(x) (((x) & COMPHY_MODE_MASK) >> \
65*54fd6939SJiyong Park COMPHY_MODE_OFFSET)
66*54fd6939SJiyong Park /* Macro which extracts unit index from lane description */
67*54fd6939SJiyong Park #define COMPHY_GET_ID(x) (((x) & COMPHY_UNIT_ID_MASK) >> \
68*54fd6939SJiyong Park COMPHY_UNIT_ID_OFFSET)
69*54fd6939SJiyong Park /* Macro which extracts speed from lane description */
70*54fd6939SJiyong Park #define COMPHY_GET_SPEED(x) (((x) & COMPHY_SPEED_MASK) >> \
71*54fd6939SJiyong Park COMPHY_SPEED_OFFSET)
72*54fd6939SJiyong Park /* Macro which extracts clock source indication from lane description */
73*54fd6939SJiyong Park #define COMPHY_GET_CLK_SRC(x) (((x) & COMPHY_CLK_SRC_MASK) >> \
74*54fd6939SJiyong Park COMPHY_CLK_SRC_OFFSET)
75*54fd6939SJiyong Park /* Macro which extracts pcie width indication from lane description */
76*54fd6939SJiyong Park #define COMPHY_GET_PCIE_WIDTH(x) (((x) & COMPHY_PCI_WIDTH_MASK) >> \
77*54fd6939SJiyong Park COMPHY_PCI_WIDTH_OFFSET)
78*54fd6939SJiyong Park
79*54fd6939SJiyong Park /* Macro which extracts the caller for pcie power on from lane description */
80*54fd6939SJiyong Park #define COMPHY_GET_CALLER(x) (((x) & COMPHY_PCI_CALLER_MASK) >> \
81*54fd6939SJiyong Park COMPHY_PCI_CALLER_OFFSET)
82*54fd6939SJiyong Park
83*54fd6939SJiyong Park /* Macro which extracts the polarity invert from lane description */
84*54fd6939SJiyong Park #define COMPHY_GET_POLARITY_INVERT(x) (((x) & COMPHY_INVERT_MASK) >> \
85*54fd6939SJiyong Park COMPHY_INVERT_OFFSET)
86*54fd6939SJiyong Park
87*54fd6939SJiyong Park
88*54fd6939SJiyong Park #define COMPHY_SATA_MODE 0x1
89*54fd6939SJiyong Park #define COMPHY_SGMII_MODE 0x2 /* SGMII 1G */
90*54fd6939SJiyong Park #define COMPHY_2500BASEX_MODE 0x3 /* 2500Base-X */
91*54fd6939SJiyong Park #define COMPHY_USB3H_MODE 0x4
92*54fd6939SJiyong Park #define COMPHY_USB3D_MODE 0x5
93*54fd6939SJiyong Park #define COMPHY_PCIE_MODE 0x6
94*54fd6939SJiyong Park #define COMPHY_RXAUI_MODE 0x7
95*54fd6939SJiyong Park #define COMPHY_XFI_MODE 0x8
96*54fd6939SJiyong Park #define COMPHY_SFI_MODE 0x9
97*54fd6939SJiyong Park #define COMPHY_USB3_MODE 0xa
98*54fd6939SJiyong Park #define COMPHY_AP_MODE 0xb
99*54fd6939SJiyong Park
100*54fd6939SJiyong Park #define COMPHY_UNUSED 0xFFFFFFFF
101*54fd6939SJiyong Park
102*54fd6939SJiyong Park /* Polarity invert macro */
103*54fd6939SJiyong Park #define COMPHY_POLARITY_NO_INVERT 0
104*54fd6939SJiyong Park #define COMPHY_POLARITY_TXD_INVERT 1
105*54fd6939SJiyong Park #define COMPHY_POLARITY_RXD_INVERT 2
106*54fd6939SJiyong Park #define COMPHY_POLARITY_ALL_INVERT (COMPHY_POLARITY_TXD_INVERT | \
107*54fd6939SJiyong Park COMPHY_POLARITY_RXD_INVERT)
108*54fd6939SJiyong Park
109*54fd6939SJiyong Park enum reg_width_type {
110*54fd6939SJiyong Park REG_16BIT = 0,
111*54fd6939SJiyong Park REG_32BIT,
112*54fd6939SJiyong Park };
113*54fd6939SJiyong Park
114*54fd6939SJiyong Park enum {
115*54fd6939SJiyong Park COMPHY_LANE0 = 0,
116*54fd6939SJiyong Park COMPHY_LANE1,
117*54fd6939SJiyong Park COMPHY_LANE2,
118*54fd6939SJiyong Park COMPHY_LANE3,
119*54fd6939SJiyong Park COMPHY_LANE4,
120*54fd6939SJiyong Park COMPHY_LANE5,
121*54fd6939SJiyong Park COMPHY_LANE_MAX,
122*54fd6939SJiyong Park };
123*54fd6939SJiyong Park
polling_with_timeout(uintptr_t addr,uint32_t val,uint32_t mask,uint32_t usec_timeout,enum reg_width_type type)124*54fd6939SJiyong Park static inline uint32_t polling_with_timeout(uintptr_t addr, uint32_t val,
125*54fd6939SJiyong Park uint32_t mask,
126*54fd6939SJiyong Park uint32_t usec_timeout,
127*54fd6939SJiyong Park enum reg_width_type type)
128*54fd6939SJiyong Park {
129*54fd6939SJiyong Park uint32_t data;
130*54fd6939SJiyong Park
131*54fd6939SJiyong Park do {
132*54fd6939SJiyong Park udelay(1);
133*54fd6939SJiyong Park if (type == REG_16BIT)
134*54fd6939SJiyong Park data = mmio_read_16(addr) & mask;
135*54fd6939SJiyong Park else
136*54fd6939SJiyong Park data = mmio_read_32(addr) & mask;
137*54fd6939SJiyong Park } while (data != val && --usec_timeout > 0);
138*54fd6939SJiyong Park
139*54fd6939SJiyong Park if (usec_timeout == 0)
140*54fd6939SJiyong Park return data;
141*54fd6939SJiyong Park
142*54fd6939SJiyong Park return 0;
143*54fd6939SJiyong Park }
144*54fd6939SJiyong Park
reg_set(uintptr_t addr,uint32_t data,uint32_t mask)145*54fd6939SJiyong Park static inline void reg_set(uintptr_t addr, uint32_t data, uint32_t mask)
146*54fd6939SJiyong Park {
147*54fd6939SJiyong Park debug("<atf>: WR to addr = 0x%lx, data = 0x%x (mask = 0x%x) - ",
148*54fd6939SJiyong Park addr, data, mask);
149*54fd6939SJiyong Park debug("old value = 0x%x ==> ", mmio_read_32(addr));
150*54fd6939SJiyong Park mmio_clrsetbits_32(addr, mask, data);
151*54fd6939SJiyong Park
152*54fd6939SJiyong Park debug("new val 0x%x\n", mmio_read_32(addr));
153*54fd6939SJiyong Park }
154*54fd6939SJiyong Park
reg_set16(uintptr_t addr,uint16_t data,uint16_t mask)155*54fd6939SJiyong Park static inline void __unused reg_set16(uintptr_t addr, uint16_t data,
156*54fd6939SJiyong Park uint16_t mask)
157*54fd6939SJiyong Park {
158*54fd6939SJiyong Park
159*54fd6939SJiyong Park debug("<atf>: WR to addr = 0x%lx, data = 0x%x (mask = 0x%x) - ",
160*54fd6939SJiyong Park addr, data, mask);
161*54fd6939SJiyong Park debug("old value = 0x%x ==> ", mmio_read_16(addr));
162*54fd6939SJiyong Park mmio_clrsetbits_16(addr, mask, data);
163*54fd6939SJiyong Park
164*54fd6939SJiyong Park debug("new val 0x%x\n", mmio_read_16(addr));
165*54fd6939SJiyong Park }
166*54fd6939SJiyong Park
167*54fd6939SJiyong Park #endif /* PHY_COMPHY_COMMON_H */
168