xref: /linux/drivers/bcma/core.c (revision 60063497a95e716c9a689af3be2687d261f115b4)
1 /*
2  * Broadcom specific AMBA
3  * Core ops
4  *
5  * Licensed under the GNU/GPL. See COPYING for details.
6  */
7 
8 #include "bcma_private.h"
9 #include <linux/bcma/bcma.h>
10 
11 bool bcma_core_is_enabled(struct bcma_device *core)
12 {
13 	if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
14 	    != BCMA_IOCTL_CLK)
15 		return false;
16 	if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
17 		return false;
18 	return true;
19 }
20 EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
21 
22 void bcma_core_disable(struct bcma_device *core, u32 flags)
23 {
24 	if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
25 		return;
26 
27 	bcma_awrite32(core, BCMA_IOCTL, flags);
28 	bcma_aread32(core, BCMA_IOCTL);
29 	udelay(10);
30 
31 	bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
32 	udelay(1);
33 }
34 EXPORT_SYMBOL_GPL(bcma_core_disable);
35 
36 int bcma_core_enable(struct bcma_device *core, u32 flags)
37 {
38 	bcma_core_disable(core, flags);
39 
40 	bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
41 	bcma_aread32(core, BCMA_IOCTL);
42 
43 	bcma_awrite32(core, BCMA_RESET_CTL, 0);
44 	udelay(1);
45 
46 	bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
47 	bcma_aread32(core, BCMA_IOCTL);
48 	udelay(1);
49 
50 	return 0;
51 }
52 EXPORT_SYMBOL_GPL(bcma_core_enable);
53 
54 void bcma_core_set_clockmode(struct bcma_device *core,
55 			     enum bcma_clkmode clkmode)
56 {
57 	u16 i;
58 
59 	WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
60 		core->id.id != BCMA_CORE_PCIE &&
61 		core->id.id != BCMA_CORE_80211);
62 
63 	switch (clkmode) {
64 	case BCMA_CLKMODE_FAST:
65 		bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
66 		udelay(64);
67 		for (i = 0; i < 1500; i++) {
68 			if (bcma_read32(core, BCMA_CLKCTLST) &
69 			    BCMA_CLKCTLST_HAVEHT) {
70 				i = 0;
71 				break;
72 			}
73 			udelay(10);
74 		}
75 		if (i)
76 			pr_err("HT force timeout\n");
77 		break;
78 	case BCMA_CLKMODE_DYNAMIC:
79 		pr_warn("Dynamic clockmode not supported yet!\n");
80 		break;
81 	}
82 }
83 EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
84 
85 void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
86 {
87 	u16 i;
88 
89 	WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
90 	WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
91 
92 	if (on) {
93 		bcma_set32(core, BCMA_CLKCTLST, req);
94 		for (i = 0; i < 10000; i++) {
95 			if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
96 			    status) {
97 				i = 0;
98 				break;
99 			}
100 			udelay(10);
101 		}
102 		if (i)
103 			pr_err("PLL enable timeout\n");
104 	} else {
105 		pr_warn("Disabling PLL not supported yet!\n");
106 	}
107 }
108 EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
109 
110 u32 bcma_core_dma_translation(struct bcma_device *core)
111 {
112 	switch (core->bus->hosttype) {
113 	case BCMA_HOSTTYPE_PCI:
114 		if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
115 			return BCMA_DMA_TRANSLATION_DMA64_CMT;
116 		else
117 			return BCMA_DMA_TRANSLATION_DMA32_CMT;
118 	default:
119 		pr_err("DMA translation unknown for host %d\n",
120 		       core->bus->hosttype);
121 	}
122 	return BCMA_DMA_TRANSLATION_NONE;
123 }
124 EXPORT_SYMBOL(bcma_core_dma_translation);
125