33#include <linux/delay.h>
44#include <linux/clk-provider.h>
55#include <linux/io.h>
6+ #include <linux/mfd/syscon.h>
67#include <linux/platform_device.h>
78#include <linux/property.h>
9+ #include <linux/regmap.h>
810#include <linux/reset-controller.h>
911#include <dt-bindings/clock/en7523-clk.h>
1012#include <dt-bindings/reset/airoha,en7581-reset.h>
@@ -247,15 +249,11 @@ static const u16 en7581_rst_map[] = {
247249 [EN7581_XPON_MAC_RST ] = RST_NR_PER_BANK + 31 ,
248250};
249251
250- static unsigned int en7523_get_base_rate (void __iomem * base , unsigned int i )
252+ static u32 en7523_get_base_rate (const struct en_clk_desc * desc , u32 val )
251253{
252- const struct en_clk_desc * desc = & en7523_base_clks [i ];
253- u32 val ;
254-
255254 if (!desc -> base_bits )
256255 return desc -> base_value ;
257256
258- val = readl (base + desc -> base_reg );
259257 val >>= desc -> base_shift ;
260258 val &= (1 << desc -> base_bits ) - 1 ;
261259
@@ -265,16 +263,11 @@ static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
265263 return desc -> base_values [val ];
266264}
267265
268- static u32 en7523_get_div (void __iomem * base , int i )
266+ static u32 en7523_get_div (const struct en_clk_desc * desc , u32 val )
269267{
270- const struct en_clk_desc * desc = & en7523_base_clks [i ];
271- u32 reg , val ;
272-
273268 if (!desc -> div_bits )
274269 return 1 ;
275270
276- reg = desc -> div_reg ? desc -> div_reg : desc -> base_reg ;
277- val = readl (base + reg );
278271 val >>= desc -> div_shift ;
279272 val &= (1 << desc -> div_bits ) - 1 ;
280273
@@ -416,9 +409,12 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat
416409
417410 for (i = 0 ; i < ARRAY_SIZE (en7523_base_clks ); i ++ ) {
418411 const struct en_clk_desc * desc = & en7523_base_clks [i ];
412+ u32 reg = desc -> div_reg ? desc -> div_reg : desc -> base_reg ;
413+ u32 val = readl (base + desc -> base_reg );
419414
420- rate = en7523_get_base_rate (base , i );
421- rate /= en7523_get_div (base , i );
415+ rate = en7523_get_base_rate (desc , val );
416+ val = readl (base + reg );
417+ rate /= en7523_get_div (desc , val );
422418
423419 hw = clk_hw_register_fixed_rate (dev , desc -> name , NULL , 0 , rate );
424420 if (IS_ERR (hw )) {
@@ -454,21 +450,66 @@ static int en7523_clk_hw_init(struct platform_device *pdev,
454450 return 0 ;
455451}
456452
453+ static void en7581_register_clocks (struct device * dev , struct clk_hw_onecell_data * clk_data ,
454+ struct regmap * map , void __iomem * base )
455+ {
456+ struct clk_hw * hw ;
457+ u32 rate ;
458+ int i ;
459+
460+ for (i = 0 ; i < ARRAY_SIZE (en7523_base_clks ); i ++ ) {
461+ const struct en_clk_desc * desc = & en7523_base_clks [i ];
462+ u32 val , reg = desc -> div_reg ? desc -> div_reg : desc -> base_reg ;
463+ int err ;
464+
465+ err = regmap_read (map , desc -> base_reg , & val );
466+ if (err ) {
467+ pr_err ("Failed reading fixed clk rate %s: %d\n" ,
468+ desc -> name , err );
469+ continue ;
470+ }
471+ rate = en7523_get_base_rate (desc , val );
472+
473+ err = regmap_read (map , reg , & val );
474+ if (err ) {
475+ pr_err ("Failed reading fixed clk div %s: %d\n" ,
476+ desc -> name , err );
477+ continue ;
478+ }
479+ rate /= en7523_get_div (desc , val );
480+
481+ hw = clk_hw_register_fixed_rate (dev , desc -> name , NULL , 0 , rate );
482+ if (IS_ERR (hw )) {
483+ pr_err ("Failed to register clk %s: %ld\n" ,
484+ desc -> name , PTR_ERR (hw ));
485+ continue ;
486+ }
487+
488+ clk_data -> hws [desc -> id ] = hw ;
489+ }
490+
491+ hw = en7523_register_pcie_clk (dev , base );
492+ clk_data -> hws [EN7523_CLK_PCIE ] = hw ;
493+
494+ clk_data -> num = EN7523_NUM_CLOCKS ;
495+ }
496+
457497static int en7581_clk_hw_init (struct platform_device * pdev ,
458498 struct clk_hw_onecell_data * clk_data )
459499{
460- void __iomem * base , * np_base ;
500+ void __iomem * np_base ;
501+ struct regmap * map ;
461502 u32 val ;
462503
463- base = devm_platform_ioremap_resource ( pdev , 0 );
464- if (IS_ERR (base ))
465- return PTR_ERR (base );
504+ map = syscon_regmap_lookup_by_compatible ( "airoha,en7581-chip-scu" );
505+ if (IS_ERR (map ))
506+ return PTR_ERR (map );
466507
467- np_base = devm_platform_ioremap_resource (pdev , 1 );
508+ np_base = devm_platform_ioremap_resource (pdev , 0 );
468509 if (IS_ERR (np_base ))
469510 return PTR_ERR (np_base );
470511
471- en7523_register_clocks (& pdev -> dev , clk_data , base , np_base );
512+ en7581_register_clocks (& pdev -> dev , clk_data , map , np_base );
472513
473514 val = readl (np_base + REG_NP_SCU_SSTR );
474515 val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK );
@@ -545,7 +586,7 @@ static int en7523_reset_register(struct platform_device *pdev,
545586 if (!soc_data -> reset .idx_map_nr )
546587 return 0 ;
547588
548- base = devm_platform_ioremap_resource (pdev , 2 );
589+ base = devm_platform_ioremap_resource (pdev , 1 );
549590 if (IS_ERR (base ))
550591 return PTR_ERR (base );
551592
0 commit comments