2222#include <linux/property.h>
2323
2424#include "mlxbf_gige.h"
25+ #include "mlxbf_gige_regs.h"
2526
2627#define MLXBF_GIGE_MDIO_GW_OFFSET 0x0
2728#define MLXBF_GIGE_MDIO_CFG_OFFSET 0x4
2829
30+ #define MLXBF_GIGE_MDIO_FREQ_REFERENCE 156250000ULL
31+ #define MLXBF_GIGE_MDIO_COREPLL_CONST 16384ULL
32+ #define MLXBF_GIGE_MDC_CLK_NS 400
33+ #define MLXBF_GIGE_MDIO_PLL_I1CLK_REG1 0x4
34+ #define MLXBF_GIGE_MDIO_PLL_I1CLK_REG2 0x8
35+ #define MLXBF_GIGE_MDIO_CORE_F_SHIFT 0
36+ #define MLXBF_GIGE_MDIO_CORE_F_MASK GENMASK(25, 0)
37+ #define MLXBF_GIGE_MDIO_CORE_R_SHIFT 26
38+ #define MLXBF_GIGE_MDIO_CORE_R_MASK GENMASK(31, 26)
39+ #define MLXBF_GIGE_MDIO_CORE_OD_SHIFT 0
40+ #define MLXBF_GIGE_MDIO_CORE_OD_MASK GENMASK(3, 0)
41+
2942/* Support clause 22 */
3043#define MLXBF_GIGE_MDIO_CL22_ST1 0x1
3144#define MLXBF_GIGE_MDIO_CL22_WRITE 0x1
5063#define MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK GENMASK(23, 16)
5164#define MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK GENMASK(31, 24)
5265
66+ #define MLXBF_GIGE_MDIO_CFG_VAL (FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_MODE_MASK, 1) | \
67+ FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO3_3_MASK, 1) | \
68+ FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK, 1) | \
69+ FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK, 6) | \
70+ FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK, 13))
71+
72+ #define MLXBF_GIGE_BF2_COREPLL_ADDR 0x02800c30
73+ #define MLXBF_GIGE_BF2_COREPLL_SIZE 0x0000000c
74+
75+ static struct resource corepll_params [] = {
76+ [MLXBF_GIGE_VERSION_BF2 ] = {
77+ .start = MLXBF_GIGE_BF2_COREPLL_ADDR ,
78+ .end = MLXBF_GIGE_BF2_COREPLL_ADDR + MLXBF_GIGE_BF2_COREPLL_SIZE - 1 ,
79+ .name = "COREPLL_RES"
80+ },
81+ };
82+
83+ /* Returns core clock i1clk in Hz */
84+ static u64 calculate_i1clk (struct mlxbf_gige * priv )
85+ {
86+ u8 core_od , core_r ;
87+ u64 freq_output ;
88+ u32 reg1 , reg2 ;
89+ u32 core_f ;
90+
91+ reg1 = readl (priv -> clk_io + MLXBF_GIGE_MDIO_PLL_I1CLK_REG1 );
92+ reg2 = readl (priv -> clk_io + MLXBF_GIGE_MDIO_PLL_I1CLK_REG2 );
93+
94+ core_f = (reg1 & MLXBF_GIGE_MDIO_CORE_F_MASK ) >>
95+ MLXBF_GIGE_MDIO_CORE_F_SHIFT ;
96+ core_r = (reg1 & MLXBF_GIGE_MDIO_CORE_R_MASK ) >>
97+ MLXBF_GIGE_MDIO_CORE_R_SHIFT ;
98+ core_od = (reg2 & MLXBF_GIGE_MDIO_CORE_OD_MASK ) >>
99+ MLXBF_GIGE_MDIO_CORE_OD_SHIFT ;
100+
101+ /* Compute PLL output frequency as follow:
102+ *
103+ * CORE_F / 16384
104+ * freq_output = freq_reference * ----------------------------
105+ * (CORE_R + 1) * (CORE_OD + 1)
106+ */
107+ freq_output = div_u64 ((MLXBF_GIGE_MDIO_FREQ_REFERENCE * core_f ),
108+ MLXBF_GIGE_MDIO_COREPLL_CONST );
109+ freq_output = div_u64 (freq_output , (core_r + 1 ) * (core_od + 1 ));
110+
111+ return freq_output ;
112+ }
113+
53114/* Formula for encoding the MDIO period. The encoded value is
54115 * passed to the MDIO config register.
55116 *
56- * mdc_clk = 2*(val + 1)*i1clk
117+ * mdc_clk = 2*(val + 1)*(core clock in sec)
57118 *
58- * 400 ns = 2*(val + 1)*(((1/430)*1000) ns)
119+ * i1clk is in Hz:
120+ * 400 ns = 2*(val + 1)*(1/i1clk)
59121 *
60- * val = (((400 * 430 / 1000) / 2) - 1)
122+ * val = (((400/10^9) / (1/i1clk) / 2) - 1)
123+ * val = (400/2 * i1clk)/10^9 - 1
61124 */
62- #define MLXBF_GIGE_I1CLK_MHZ 430
63- #define MLXBF_GIGE_MDC_CLK_NS 400
125+ static u8 mdio_period_map (struct mlxbf_gige * priv )
126+ {
127+ u8 mdio_period ;
128+ u64 i1clk ;
64129
65- #define MLXBF_GIGE_MDIO_PERIOD (((MLXBF_GIGE_MDC_CLK_NS * MLXBF_GIGE_I1CLK_MHZ / 1000) / 2) - 1)
130+ i1clk = calculate_i1clk ( priv );
66131
67- #define MLXBF_GIGE_MDIO_CFG_VAL (FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_MODE_MASK, 1) | \
68- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO3_3_MASK, 1) | \
69- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK, 1) | \
70- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDC_PERIOD_MASK, \
71- MLXBF_GIGE_MDIO_PERIOD) | \
72- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK, 6) | \
73- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK, 13))
132+ mdio_period = div_u64 ((MLXBF_GIGE_MDC_CLK_NS >> 1 ) * i1clk , 1000000000 ) - 1 ;
133+
134+ return mdio_period ;
135+ }
74136
75137static u32 mlxbf_gige_mdio_create_cmd (u16 data , int phy_add ,
76138 int phy_reg , u32 opcode )
@@ -124,9 +186,9 @@ static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,
124186 int phy_reg , u16 val )
125187{
126188 struct mlxbf_gige * priv = bus -> priv ;
189+ u32 temp ;
127190 u32 cmd ;
128191 int ret ;
129- u32 temp ;
130192
131193 if (phy_reg & MII_ADDR_C45 )
132194 return - EOPNOTSUPP ;
@@ -144,18 +206,44 @@ static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,
144206 return ret ;
145207}
146208
209+ static void mlxbf_gige_mdio_cfg (struct mlxbf_gige * priv )
210+ {
211+ u8 mdio_period ;
212+ u32 val ;
213+
214+ mdio_period = mdio_period_map (priv );
215+
216+ val = MLXBF_GIGE_MDIO_CFG_VAL ;
217+ val |= FIELD_PREP (MLXBF_GIGE_MDIO_CFG_MDC_PERIOD_MASK , mdio_period );
218+ writel (val , priv -> mdio_io + MLXBF_GIGE_MDIO_CFG_OFFSET );
219+ }
220+
147221int mlxbf_gige_mdio_probe (struct platform_device * pdev , struct mlxbf_gige * priv )
148222{
149223 struct device * dev = & pdev -> dev ;
224+ struct resource * res ;
150225 int ret ;
151226
152227 priv -> mdio_io = devm_platform_ioremap_resource (pdev , MLXBF_GIGE_RES_MDIO9 );
153228 if (IS_ERR (priv -> mdio_io ))
154229 return PTR_ERR (priv -> mdio_io );
155230
156- /* Configure mdio parameters */
157- writel (MLXBF_GIGE_MDIO_CFG_VAL ,
158- priv -> mdio_io + MLXBF_GIGE_MDIO_CFG_OFFSET );
231+ /* clk resource shared with other drivers so cannot use
232+ * devm_platform_ioremap_resource
233+ */
234+ res = platform_get_resource (pdev , IORESOURCE_MEM , MLXBF_GIGE_RES_CLK );
235+ if (!res ) {
236+ /* For backward compatibility with older ACPI tables, also keep
237+ * CLK resource internal to the driver.
238+ */
239+ res = & corepll_params [MLXBF_GIGE_VERSION_BF2 ];
240+ }
241+
242+ priv -> clk_io = devm_ioremap (dev , res -> start , resource_size (res ));
243+ if (IS_ERR (priv -> clk_io ))
244+ return PTR_ERR (priv -> clk_io );
245+
246+ mlxbf_gige_mdio_cfg (priv );
159247
160248 priv -> mdiobus = devm_mdiobus_alloc (dev );
161249 if (!priv -> mdiobus ) {
0 commit comments