1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2015-2016 Marvell International Ltd.
4  */
5 
6 #ifndef _COMPHY_CORE_H_
7 #define _COMPHY_CORE_H_
8 
9 #include <fdtdec.h>
10 #include <mvebu/comphy.h>
11 #include <dt-bindings/comphy/comphy_data.h>
12 
13 #if defined(DEBUG)
14 #define debug_enter()	printf("----> Enter %s\n", __func__);
15 #define debug_exit()	printf("<---- Exit  %s\n", __func__);
16 #else
17 #define debug_enter()
18 #define debug_exit()
19 #endif
20 
21 #define MAX_LANE_OPTIONS			10
22 #define MAX_UTMI_PHY_COUNT			6
23 
24 struct comphy_map {
25 	u32 type;
26 	u32 speed;
27 	u32 invert;
28 	bool clk_src;
29 	bool end_point;
30 };
31 
32 struct comphy_mux_options {
33 	u32 type;
34 	u32 mux_value;
35 };
36 
37 struct comphy_mux_data {
38 	u32 max_lane_values;
39 	struct comphy_mux_options mux_values[MAX_LANE_OPTIONS];
40 };
41 
42 struct chip_serdes_phy_config {
43 	struct comphy_mux_data *mux_data;
44 	int (*comphy_init_map)(int, struct chip_serdes_phy_config *);
45 	int (*ptr_comphy_chip_init)(struct chip_serdes_phy_config *,
46 				    struct comphy_map *);
47 	int (*rx_training)(struct chip_serdes_phy_config *, u32);
48 	void __iomem *comphy_base_addr;
49 	void __iomem *hpipe3_base_addr;
50 	u32 comphy_lanes_count;
51 	u32 comphy_mux_bitcount;
52 	const fdt32_t *comphy_mux_lane_order;
53 	u32 cp_index;
54 	struct comphy_map comphy_map_data[MAX_LANE_OPTIONS];
55 };
56 
57 /* Register helper functions */
reg_set_silent(void __iomem * addr,u32 data,u32 mask)58 static inline void reg_set_silent(void __iomem *addr, u32 data, u32 mask)
59 {
60 	u32 reg_data;
61 
62 	reg_data = readl(addr);
63 	reg_data &= ~mask;
64 	reg_data |= data;
65 	writel(reg_data, addr);
66 }
67 
reg_set(void __iomem * addr,u32 data,u32 mask)68 static inline void reg_set(void __iomem *addr, u32 data, u32 mask)
69 {
70 	debug("Write to address = %#010lx, data = %#010x (mask = %#010x) - ",
71 	      (unsigned long)addr, data, mask);
72 	debug("old value = %#010x ==> ", readl(addr));
73 	reg_set_silent(addr, data, mask);
74 	debug("new value %#010x\n", readl(addr));
75 }
76 
reg_set_silent16(void __iomem * addr,u16 data,u16 mask)77 static inline void reg_set_silent16(void __iomem *addr, u16 data, u16 mask)
78 {
79 	u16 reg_data;
80 
81 	reg_data = readw(addr);
82 	reg_data &= ~mask;
83 	reg_data |= data;
84 	writew(reg_data, addr);
85 }
86 
reg_set16(void __iomem * addr,u16 data,u16 mask)87 static inline void reg_set16(void __iomem *addr, u16 data, u16 mask)
88 {
89 	debug("Write to address = %#010lx, data = %#06x (mask = %#06x) - ",
90 	      (unsigned long)addr, data, mask);
91 	debug("old value = %#06x ==> ", readw(addr));
92 	reg_set_silent16(addr, data, mask);
93 	debug("new value %#06x\n", readw(addr));
94 }
95 
96 /* SoC specific init functions */
97 #ifdef CONFIG_ARMADA_3700
98 int comphy_a3700_init_serdes_map(int node, struct chip_serdes_phy_config *cfg);
99 int comphy_a3700_init(struct chip_serdes_phy_config *ptr_chip_cfg,
100 		      struct comphy_map *serdes_map);
101 #else
102 static inline int
comphy_a3700_init_serdes_map(int node,struct chip_serdes_phy_config * cfg)103 comphy_a3700_init_serdes_map(int node, struct chip_serdes_phy_config *cfg)
104 {
105 	/*
106 	 * This function should never be called in this configuration, so
107 	 * lets return an error here.
108 	 */
109 	return -1;
110 }
111 
comphy_a3700_init(struct chip_serdes_phy_config * ptr_chip_cfg,struct comphy_map * serdes_map)112 static inline int comphy_a3700_init(struct chip_serdes_phy_config *ptr_chip_cfg,
113 				    struct comphy_map *serdes_map)
114 {
115 	/*
116 	 * This function should never be called in this configuration, so
117 	 * lets return an error here.
118 	 */
119 	return -1;
120 }
121 #endif
122 
123 #ifdef CONFIG_ARMADA_8K
124 int comphy_cp110_init_serdes_map(int node, struct chip_serdes_phy_config *cfg);
125 int comphy_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg,
126 		      struct comphy_map *serdes_map);
127 int comphy_cp110_sfi_rx_training(struct chip_serdes_phy_config *ptr_chip_cfg,
128 				 u32 lane);
129 #else
130 static inline int
comphy_cp110_init_serdes_map(int node,struct chip_serdes_phy_config * cfg)131 comphy_cp110_init_serdes_map(int node, struct chip_serdes_phy_config *cfg)
132 {
133 	/*
134 	 * This function should never be called in this configuration, so
135 	 * lets return an error here.
136 	 */
137 	return -1;
138 }
139 
comphy_cp110_init(struct chip_serdes_phy_config * ptr_chip_cfg,struct comphy_map * serdes_map)140 static inline int comphy_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg,
141 		      struct comphy_map *serdes_map)
142 {
143 	/*
144 	 * This function should never be called in this configuration, so
145 	 * lets return an error here.
146 	 */
147 	return -1;
148 }
149 
comphy_cp110_sfi_rx_training(struct chip_serdes_phy_config * ptr_chip_cfg,u32 lane)150 static inline int comphy_cp110_sfi_rx_training(
151 	struct chip_serdes_phy_config *ptr_chip_cfg,
152 	u32 lane)
153 {
154 	/*
155 	 * This function should never be called in this configuration, so
156 	 * lets return an error here.
157 	 */
158 	return -1;
159 }
160 #endif
161 
162 void comphy_dedicated_phys_init(void);
163 
164 /* MUX function */
165 void comphy_mux_init(struct chip_serdes_phy_config *ptr_chip_cfg,
166 		     struct comphy_map *comphy_map_data,
167 		     void __iomem *selector_base);
168 
169 void comphy_pcie_config_set(u32 comphy_max_count,
170 			    struct comphy_map *serdes_map);
171 void comphy_pcie_config_detect(u32 comphy_max_count,
172 			       struct comphy_map *serdes_map);
173 void comphy_pcie_unit_general_config(u32 pex_index);
174 
175 #endif /* _COMPHY_CORE_H_ */
176