1010#define REG_PCI_CONTROL 0x88
1111#define REG_PCI_CONTROL_PERSTOUT BIT(29)
1212#define REG_PCI_CONTROL_PERSTOUT1 BIT(26)
13+ #define REG_PCI_CONTROL_REFCLK_EN0 BIT(23)
1314#define REG_PCI_CONTROL_REFCLK_EN1 BIT(22)
15+ #define REG_PCI_CONTROL_PERSTOUT2 BIT(16)
1416#define REG_GSW_CLK_DIV_SEL 0x1b4
1517#define REG_EMI_CLK_DIV_SEL 0x1b8
1618#define REG_BUS_CLK_DIV_SEL 0x1bc
1719#define REG_SPI_CLK_DIV_SEL 0x1c4
1820#define REG_SPI_CLK_FREQ_SEL 0x1c8
1921#define REG_NPU_CLK_DIV_SEL 0x1fc
2022#define REG_CRYPTO_CLKSRC 0x200
21- #define REG_RESET_CONTROL 0x834
23+ #define REG_RESET_CONTROL2 0x830
24+ #define REG_RESET2_CONTROL_PCIE2 BIT(27)
25+ #define REG_RESET_CONTROL1 0x834
2226#define REG_RESET_CONTROL_PCIEHB BIT(29)
2327#define REG_RESET_CONTROL_PCIE1 BIT(27)
2428#define REG_RESET_CONTROL_PCIE2 BIT(26)
29+ /* EN7581 */
30+ #define REG_PCIE0_MEM 0x00
31+ #define REG_PCIE0_MEM_MASK 0x04
32+ #define REG_PCIE1_MEM 0x08
33+ #define REG_PCIE1_MEM_MASK 0x0c
34+ #define REG_PCIE2_MEM 0x10
35+ #define REG_PCIE2_MEM_MASK 0x14
36+ #define REG_PCIE_RESET_OPEN_DRAIN 0x018c
37+ #define REG_PCIE_RESET_OPEN_DRAIN_MASK GENMASK(2, 0)
38+ #define REG_NP_SCU_PCIC 0x88
39+ #define REG_NP_SCU_SSTR 0x9c
40+ #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)
41+ #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
2542
2643struct en_clk_desc {
2744 int id ;
@@ -49,6 +66,8 @@ struct en_clk_gate {
4966
5067struct en_clk_soc_data {
5168 const struct clk_ops pcie_ops ;
69+ int (* hw_init )(struct platform_device * pdev , void __iomem * base ,
70+ void __iomem * np_base );
5271};
5372
5473static const u32 gsw_base [] = { 400000000 , 500000000 };
@@ -211,14 +230,14 @@ static int en7523_pci_prepare(struct clk_hw *hw)
211230 usleep_range (1000 , 2000 );
212231
213232 /* Reset to default */
214- val = readl (np_base + REG_RESET_CONTROL );
233+ val = readl (np_base + REG_RESET_CONTROL1 );
215234 mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
216235 REG_RESET_CONTROL_PCIEHB ;
217- writel (val & ~mask , np_base + REG_RESET_CONTROL );
236+ writel (val & ~mask , np_base + REG_RESET_CONTROL1 );
218237 usleep_range (1000 , 2000 );
219- writel (val | mask , np_base + REG_RESET_CONTROL );
238+ writel (val | mask , np_base + REG_RESET_CONTROL1 );
220239 msleep (100 );
221- writel (val & ~mask , np_base + REG_RESET_CONTROL );
240+ writel (val & ~mask , np_base + REG_RESET_CONTROL1 );
222241 usleep_range (5000 , 10000 );
223242
224243 /* Release device */
@@ -259,6 +278,9 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
259278
260279 cg -> base = np_base ;
261280 cg -> hw .init = & init ;
281+
282+ if (init .ops -> disable )
283+ init .ops -> disable (& cg -> hw );
262284 init .ops -> unprepare (& cg -> hw );
263285
264286 if (clk_hw_register (dev , & cg -> hw ))
@@ -267,6 +289,111 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
267289 return & cg -> hw ;
268290}
269291
292+ static int en7581_pci_is_enabled (struct clk_hw * hw )
293+ {
294+ struct en_clk_gate * cg = container_of (hw , struct en_clk_gate , hw );
295+ u32 val , mask ;
296+
297+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 ;
298+ val = readl (cg -> base + REG_PCI_CONTROL );
299+ return (val & mask ) == mask ;
300+ }
301+
302+ static int en7581_pci_prepare (struct clk_hw * hw )
303+ {
304+ struct en_clk_gate * cg = container_of (hw , struct en_clk_gate , hw );
305+ void __iomem * np_base = cg -> base ;
306+ u32 val , mask ;
307+
308+ mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
309+ REG_RESET_CONTROL_PCIEHB ;
310+ val = readl (np_base + REG_RESET_CONTROL1 );
311+ writel (val & ~mask , np_base + REG_RESET_CONTROL1 );
312+ val = readl (np_base + REG_RESET_CONTROL2 );
313+ writel (val & ~REG_RESET2_CONTROL_PCIE2 , np_base + REG_RESET_CONTROL2 );
314+ usleep_range (5000 , 10000 );
315+
316+ return 0 ;
317+ }
318+
319+ static int en7581_pci_enable (struct clk_hw * hw )
320+ {
321+ struct en_clk_gate * cg = container_of (hw , struct en_clk_gate , hw );
322+ void __iomem * np_base = cg -> base ;
323+ u32 val , mask ;
324+
325+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
326+ REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
327+ REG_PCI_CONTROL_PERSTOUT ;
328+ val = readl (np_base + REG_PCI_CONTROL );
329+ writel (val | mask , np_base + REG_PCI_CONTROL );
330+ msleep (250 );
331+
332+ return 0 ;
333+ }
334+
335+ static void en7581_pci_unprepare (struct clk_hw * hw )
336+ {
337+ struct en_clk_gate * cg = container_of (hw , struct en_clk_gate , hw );
338+ void __iomem * np_base = cg -> base ;
339+ u32 val , mask ;
340+
341+ mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
342+ REG_RESET_CONTROL_PCIEHB ;
343+ val = readl (np_base + REG_RESET_CONTROL1 );
344+ writel (val | mask , np_base + REG_RESET_CONTROL1 );
345+ mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 ;
346+ writel (val | mask , np_base + REG_RESET_CONTROL1 );
347+ val = readl (np_base + REG_RESET_CONTROL2 );
348+ writel (val | REG_RESET_CONTROL_PCIE2 , np_base + REG_RESET_CONTROL2 );
349+ msleep (100 );
350+ }
351+
352+ static void en7581_pci_disable (struct clk_hw * hw )
353+ {
354+ struct en_clk_gate * cg = container_of (hw , struct en_clk_gate , hw );
355+ void __iomem * np_base = cg -> base ;
356+ u32 val , mask ;
357+
358+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
359+ REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
360+ REG_PCI_CONTROL_PERSTOUT ;
361+ val = readl (np_base + REG_PCI_CONTROL );
362+ writel (val & ~mask , np_base + REG_PCI_CONTROL );
363+ usleep_range (1000 , 2000 );
364+ }
365+
366+ static int en7581_clk_hw_init (struct platform_device * pdev ,
367+ void __iomem * base ,
368+ void __iomem * np_base )
369+ {
370+ void __iomem * pb_base ;
371+ u32 val ;
372+
373+ pb_base = devm_platform_ioremap_resource (pdev , 2 );
374+ if (IS_ERR (pb_base ))
375+ return PTR_ERR (pb_base );
376+
377+ val = readl (np_base + REG_NP_SCU_SSTR );
378+ val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK );
379+ writel (val , np_base + REG_NP_SCU_SSTR );
380+ val = readl (np_base + REG_NP_SCU_PCIC );
381+ writel (val | 3 , np_base + REG_NP_SCU_PCIC );
382+
383+ writel (0x20000000 , pb_base + REG_PCIE0_MEM );
384+ writel (0xfc000000 , pb_base + REG_PCIE0_MEM_MASK );
385+ writel (0x24000000 , pb_base + REG_PCIE1_MEM );
386+ writel (0xfc000000 , pb_base + REG_PCIE1_MEM_MASK );
387+ writel (0x28000000 , pb_base + REG_PCIE2_MEM );
388+ writel (0xfc000000 , pb_base + REG_PCIE2_MEM_MASK );
389+
390+ val = readl (base + REG_PCIE_RESET_OPEN_DRAIN );
391+ writel (val | REG_PCIE_RESET_OPEN_DRAIN_MASK ,
392+ base + REG_PCIE_RESET_OPEN_DRAIN );
393+
394+ return 0 ;
395+ }
396+
270397static void en7523_register_clocks (struct device * dev , struct clk_hw_onecell_data * clk_data ,
271398 void __iomem * base , void __iomem * np_base )
272399{
@@ -299,6 +426,7 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat
299426static int en7523_clk_probe (struct platform_device * pdev )
300427{
301428 struct device_node * node = pdev -> dev .of_node ;
429+ const struct en_clk_soc_data * soc_data ;
302430 struct clk_hw_onecell_data * clk_data ;
303431 void __iomem * base , * np_base ;
304432 int r ;
@@ -311,6 +439,13 @@ static int en7523_clk_probe(struct platform_device *pdev)
311439 if (IS_ERR (np_base ))
312440 return PTR_ERR (np_base );
313441
442+ soc_data = device_get_match_data (& pdev -> dev );
443+ if (soc_data -> hw_init ) {
444+ r = soc_data -> hw_init (pdev , base , np_base );
445+ if (r )
446+ return r ;
447+ }
448+
314449 clk_data = devm_kzalloc (& pdev -> dev ,
315450 struct_size (clk_data , hws , EN7523_NUM_CLOCKS ),
316451 GFP_KERNEL );
@@ -336,8 +471,20 @@ static const struct en_clk_soc_data en7523_data = {
336471 },
337472};
338473
474+ static const struct en_clk_soc_data en7581_data = {
475+ .pcie_ops = {
476+ .is_enabled = en7581_pci_is_enabled ,
477+ .prepare = en7581_pci_prepare ,
478+ .enable = en7581_pci_enable ,
479+ .unprepare = en7581_pci_unprepare ,
480+ .disable = en7581_pci_disable ,
481+ },
482+ .hw_init = en7581_clk_hw_init ,
483+ };
484+
339485static const struct of_device_id of_match_clk_en7523 [] = {
340486 { .compatible = "airoha,en7523-scu" , .data = & en7523_data },
487+ { .compatible = "airoha,en7581-scu" , .data = & en7581_data },
341488 { /* sentinel */ }
342489};
343490
0 commit comments