11
11
#include <linux/clk.h>
12
12
#include <linux/delay.h>
13
13
#include <linux/iopoll.h>
14
+ #include <linux/mfd/syscon.h>
14
15
#include <linux/module.h>
15
16
#include <linux/of_address.h>
16
17
#include <linux/phy/phy.h>
17
18
#include <linux/platform_device.h>
19
+ #include <linux/regmap.h>
18
20
19
21
#include "phy-mtk-io.h"
20
22
81
83
#define XSP_SR_COEF_DIVISOR 1000
82
84
#define XSP_FM_DET_CYCLE_CNT 1024
83
85
86
+ /* PHY switch between pcie/usb3/sgmii */
87
+ #define USB_PHY_SWITCH_CTRL 0x0
88
+ #define RG_PHY_SW_TYPE GENMASK(3, 0)
89
+ #define RG_PHY_SW_PCIE 0x0
90
+ #define RG_PHY_SW_USB3 0x1
91
+ #define RG_PHY_SW_SGMII 0x2
92
+
84
93
struct xsphy_instance {
85
94
struct phy * phy ;
86
95
void __iomem * port_base ;
87
96
struct clk * ref_clk ; /* reference clock of anolog phy */
88
97
u32 index ;
89
98
u32 type ;
99
+ struct regmap * type_sw ;
100
+ u32 type_sw_reg ;
101
+ u32 type_sw_index ;
90
102
/* only for HQA test */
91
103
int efuse_intr ;
92
104
int efuse_tx_imp ;
@@ -259,6 +271,10 @@ static void phy_parse_property(struct mtk_xsphy *xsphy,
259
271
inst -> efuse_intr , inst -> efuse_tx_imp ,
260
272
inst -> efuse_rx_imp );
261
273
break ;
274
+ case PHY_TYPE_PCIE :
275
+ case PHY_TYPE_SGMII :
276
+ /* nothing to do */
277
+ break ;
262
278
default :
263
279
dev_err (xsphy -> dev , "incompatible phy type\n" );
264
280
return ;
@@ -305,6 +321,62 @@ static void u3_phy_props_set(struct mtk_xsphy *xsphy,
305
321
RG_XTP_LN0_RX_IMPSEL , inst -> efuse_rx_imp );
306
322
}
307
323
324
+ /* type switch for usb3/pcie/sgmii */
325
+ static int phy_type_syscon_get (struct xsphy_instance * instance ,
326
+ struct device_node * dn )
327
+ {
328
+ struct of_phandle_args args ;
329
+ int ret ;
330
+
331
+ /* type switch function is optional */
332
+ if (!of_property_present (dn , "mediatek,syscon-type" ))
333
+ return 0 ;
334
+
335
+ ret = of_parse_phandle_with_fixed_args (dn , "mediatek,syscon-type" ,
336
+ 2 , 0 , & args );
337
+ if (ret )
338
+ return ret ;
339
+
340
+ instance -> type_sw_reg = args .args [0 ];
341
+ instance -> type_sw_index = args .args [1 ] & 0x3 ; /* <=3 */
342
+ instance -> type_sw = syscon_node_to_regmap (args .np );
343
+ of_node_put (args .np );
344
+ dev_info (& instance -> phy -> dev , "type_sw - reg %#x, index %d\n" ,
345
+ instance -> type_sw_reg , instance -> type_sw_index );
346
+
347
+ return PTR_ERR_OR_ZERO (instance -> type_sw );
348
+ }
349
+
350
+ static int phy_type_set (struct xsphy_instance * instance )
351
+ {
352
+ int type ;
353
+ u32 offset ;
354
+
355
+ if (!instance -> type_sw )
356
+ return 0 ;
357
+
358
+ switch (instance -> type ) {
359
+ case PHY_TYPE_USB3 :
360
+ type = RG_PHY_SW_USB3 ;
361
+ break ;
362
+ case PHY_TYPE_PCIE :
363
+ type = RG_PHY_SW_PCIE ;
364
+ break ;
365
+ case PHY_TYPE_SGMII :
366
+ type = RG_PHY_SW_SGMII ;
367
+ break ;
368
+ case PHY_TYPE_USB2 :
369
+ default :
370
+ return 0 ;
371
+ }
372
+
373
+ offset = instance -> type_sw_index * BITS_PER_BYTE ;
374
+ regmap_update_bits (instance -> type_sw , instance -> type_sw_reg ,
375
+ RG_PHY_SW_TYPE << offset , type << offset );
376
+
377
+ return 0 ;
378
+ }
379
+
308
380
static int mtk_phy_init (struct phy * phy )
309
381
{
310
382
struct xsphy_instance * inst = phy_get_drvdata (phy );
@@ -325,6 +397,10 @@ static int mtk_phy_init(struct phy *phy)
325
397
case PHY_TYPE_USB3 :
326
398
u3_phy_props_set (xsphy , inst );
327
399
break ;
400
+ case PHY_TYPE_PCIE :
401
+ case PHY_TYPE_SGMII :
402
+ /* nothing to do, only used to set type */
403
+ break ;
328
404
default :
329
405
dev_err (xsphy -> dev , "incompatible phy type\n" );
330
406
clk_disable_unprepare (inst -> ref_clk );
@@ -403,12 +479,15 @@ static struct phy *mtk_phy_xlate(struct device *dev,
403
479
404
480
inst -> type = args -> args [0 ];
405
481
if (!(inst -> type == PHY_TYPE_USB2 ||
406
- inst -> type == PHY_TYPE_USB3 )) {
482
+ inst -> type == PHY_TYPE_USB3 ||
483
+ inst -> type == PHY_TYPE_PCIE ||
484
+ inst -> type == PHY_TYPE_SGMII )) {
407
485
dev_err (dev , "unsupported phy type: %d\n" , inst -> type );
408
486
return ERR_PTR (- EINVAL );
409
487
}
410
488
411
489
phy_parse_property (xsphy , inst );
490
+ phy_type_set (inst );
412
491
413
492
return inst -> phy ;
414
493
}
@@ -510,6 +589,10 @@ static int mtk_xsphy_probe(struct platform_device *pdev)
510
589
dev_err (dev , "failed to get ref_clk(id-%d)\n" , port );
511
590
return PTR_ERR (inst -> ref_clk );
512
591
}
592
+
593
+ retval = phy_type_syscon_get (inst , child_np );
594
+ if (retval )
595
+ return retval ;
513
596
}
514
597
515
598
provider = devm_of_phy_provider_register (dev , mtk_phy_xlate );
0 commit comments