Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
26dd3e4
Documentation
arch
alpha
arc
arm
arm64
avr32
blackfin
c6x
cris
frv
h8300
hexagon
ia64
m32r
m68k
metag
microblaze
mips
alchemy
ar7
ath25
ath79
bcm47xx
bcm63xx
boards
Kconfig
Makefile
Platform
clk.c
cpu.c
cs.c
dev-dsp.c
dev-enet.c
dev-flash.c
dev-hsspi.c
dev-pcmcia.c
dev-rng.c
dev-spi.c
dev-uart.c
dev-usb-usbd.c
dev-wdt.c
early_printk.c
gpio.c
irq.c
nvram.c
prom.c
reset.c
setup.c
timer.c
bmips
boot
cavium-octeon
cobalt
configs
dec
emma
fw
generic
include
jazz
jz4740
kernel
kvm
lantiq
lasat
lib
loongson32
loongson64
math-emu
mm
mti-malta
net
netlogic
oprofile
paravirt
pci
pic32
pistachio
pmcs-msp71xx
pnx833x
power
ralink
rb532
sgi-ip22
sgi-ip27
sgi-ip32
sibyte
sni
txx9
vdso
vr41xx
xilfpga
Kbuild
Kbuild.platforms
Kconfig
Kconfig.debug
Makefile
Makefile.postlink
mn10300
nios2
openrisc
parisc
powerpc
s390
score
sh
sparc
tile
um
unicore32
x86
xtensa
.gitignore
Kconfig
block
certs
crypto
drivers
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
usr
virt
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
arch
/
mips
/
bcm63xx
/
clk.c
Copy path
Blame
Blame
Latest commit
History
History
414 lines (350 loc) · 7.58 KB
Breadcrumbs
linux
/
arch
/
mips
/
bcm63xx
/
clk.c
Top
File metadata and controls
Code
Blame
414 lines (350 loc) · 7.58 KB
Raw
/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> */ #include <linux/init.h> #include <linux/export.h> #include <linux/mutex.h> #include <linux/err.h> #include <linux/clk.h> #include <linux/delay.h> #include <bcm63xx_cpu.h> #include <bcm63xx_io.h> #include <bcm63xx_regs.h> #include <bcm63xx_reset.h> struct clk { void (*set)(struct clk *, int); unsigned int rate; unsigned int usage; int id; }; static DEFINE_MUTEX(clocks_mutex); static void clk_enable_unlocked(struct clk *clk) { if (clk->set && (clk->usage++) == 0) clk->set(clk, 1); } static void clk_disable_unlocked(struct clk *clk) { if (clk->set && (--clk->usage) == 0) clk->set(clk, 0); } static void bcm_hwclock_set(u32 mask, int enable) { u32 reg; reg = bcm_perf_readl(PERF_CKCTL_REG); if (enable) reg |= mask; else reg &= ~mask; bcm_perf_writel(reg, PERF_CKCTL_REG); } /* * Ethernet MAC "misc" clock: dma clocks and main clock on 6348 */ static void enet_misc_set(struct clk *clk, int enable) { u32 mask; if (BCMCPU_IS_6338()) mask = CKCTL_6338_ENET_EN; else if (BCMCPU_IS_6345()) mask = CKCTL_6345_ENET_EN; else if (BCMCPU_IS_6348()) mask = CKCTL_6348_ENET_EN; else /* BCMCPU_IS_6358 */ mask = CKCTL_6358_EMUSB_EN; bcm_hwclock_set(mask, enable); } static struct clk clk_enet_misc = { .set = enet_misc_set, }; /* * Ethernet MAC clocks: only revelant on 6358, silently enable misc * clocks */ static void enetx_set(struct clk *clk, int enable) { if (enable) clk_enable_unlocked(&clk_enet_misc); else clk_disable_unlocked(&clk_enet_misc); if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) { u32 mask; if (clk->id == 0) mask = CKCTL_6358_ENET0_EN; else mask = CKCTL_6358_ENET1_EN; bcm_hwclock_set(mask, enable); } } static struct clk clk_enet0 = { .id = 0, .set = enetx_set, }; static struct clk clk_enet1 = { .id = 1, .set = enetx_set, }; /* * Ethernet PHY clock */ static void ephy_set(struct clk *clk, int enable) { if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable); } static struct clk clk_ephy = { .set = ephy_set, }; /* * Ethernet switch clock */ static void enetsw_set(struct clk *clk, int enable) { if (BCMCPU_IS_6328()) bcm_hwclock_set(CKCTL_6328_ROBOSW_EN, enable); else if (BCMCPU_IS_6362()) bcm_hwclock_set(CKCTL_6362_ROBOSW_EN, enable); else if (BCMCPU_IS_6368()) bcm_hwclock_set(CKCTL_6368_ROBOSW_EN | CKCTL_6368_SWPKT_USB_EN | CKCTL_6368_SWPKT_SAR_EN, enable); else return; if (enable) { /* reset switch core afer clock change */ bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1); msleep(10); bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0); msleep(10); } } static struct clk clk_enetsw = { .set = enetsw_set, }; /* * PCM clock */ static void pcm_set(struct clk *clk, int enable) { if (BCMCPU_IS_3368()) bcm_hwclock_set(CKCTL_3368_PCM_EN, enable); if (BCMCPU_IS_6358()) bcm_hwclock_set(CKCTL_6358_PCM_EN, enable); } static struct clk clk_pcm = { .set = pcm_set, }; /* * USB host clock */ static void usbh_set(struct clk *clk, int enable) { if (BCMCPU_IS_6328()) bcm_hwclock_set(CKCTL_6328_USBH_EN, enable); else if (BCMCPU_IS_6348()) bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); else if (BCMCPU_IS_6362()) bcm_hwclock_set(CKCTL_6362_USBH_EN, enable); else if (BCMCPU_IS_6368()) bcm_hwclock_set(CKCTL_6368_USBH_EN, enable); } static struct clk clk_usbh = { .set = usbh_set, }; /* * USB device clock */ static void usbd_set(struct clk *clk, int enable) { if (BCMCPU_IS_6328()) bcm_hwclock_set(CKCTL_6328_USBD_EN, enable); else if (BCMCPU_IS_6362()) bcm_hwclock_set(CKCTL_6362_USBD_EN, enable); else if (BCMCPU_IS_6368()) bcm_hwclock_set(CKCTL_6368_USBD_EN, enable); } static struct clk clk_usbd = { .set = usbd_set, }; /* * SPI clock */ static void spi_set(struct clk *clk, int enable) { u32 mask; if (BCMCPU_IS_6338()) mask = CKCTL_6338_SPI_EN; else if (BCMCPU_IS_6348()) mask = CKCTL_6348_SPI_EN; else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) mask = CKCTL_6358_SPI_EN; else if (BCMCPU_IS_6362()) mask = CKCTL_6362_SPI_EN; else /* BCMCPU_IS_6368 */ mask = CKCTL_6368_SPI_EN; bcm_hwclock_set(mask, enable); } static struct clk clk_spi = { .set = spi_set, }; /* * HSSPI clock */ static void hsspi_set(struct clk *clk, int enable) { u32 mask; if (BCMCPU_IS_6328()) mask = CKCTL_6328_HSSPI_EN; else if (BCMCPU_IS_6362()) mask = CKCTL_6362_HSSPI_EN; else return; bcm_hwclock_set(mask, enable); } static struct clk clk_hsspi = { .set = hsspi_set, }; /* * XTM clock */ static void xtm_set(struct clk *clk, int enable) { if (!BCMCPU_IS_6368()) return; bcm_hwclock_set(CKCTL_6368_SAR_EN | CKCTL_6368_SWPKT_SAR_EN, enable); if (enable) { /* reset sar core afer clock change */ bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1); mdelay(1); bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0); mdelay(1); } } static struct clk clk_xtm = { .set = xtm_set, }; /* * IPsec clock */ static void ipsec_set(struct clk *clk, int enable) { if (BCMCPU_IS_6362()) bcm_hwclock_set(CKCTL_6362_IPSEC_EN, enable); else if (BCMCPU_IS_6368()) bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable); } static struct clk clk_ipsec = { .set = ipsec_set, }; /* * PCIe clock */ static void pcie_set(struct clk *clk, int enable) { if (BCMCPU_IS_6328()) bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable); else if (BCMCPU_IS_6362()) bcm_hwclock_set(CKCTL_6362_PCIE_EN, enable); } static struct clk clk_pcie = { .set = pcie_set, }; /* * Internal peripheral clock */ static struct clk clk_periph = { .rate = (50 * 1000 * 1000), }; /* * Linux clock API implementation */ int clk_enable(struct clk *clk) { mutex_lock(&clocks_mutex); clk_enable_unlocked(clk); mutex_unlock(&clocks_mutex); return 0; } EXPORT_SYMBOL(clk_enable); void clk_disable(struct clk *clk) { if (!clk) return; mutex_lock(&clocks_mutex); clk_disable_unlocked(clk); mutex_unlock(&clocks_mutex); } EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { return clk->rate; } EXPORT_SYMBOL(clk_get_rate); int clk_set_rate(struct clk *clk, unsigned long rate) { return 0; } EXPORT_SYMBOL_GPL(clk_set_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { return 0; } EXPORT_SYMBOL_GPL(clk_round_rate); struct clk *clk_get(struct device *dev, const char *id) { if (!strcmp(id, "enet0")) return &clk_enet0; if (!strcmp(id, "enet1")) return &clk_enet1; if (!strcmp(id, "enetsw")) return &clk_enetsw; if (!strcmp(id, "ephy")) return &clk_ephy; if (!strcmp(id, "usbh")) return &clk_usbh; if (!strcmp(id, "usbd")) return &clk_usbd; if (!strcmp(id, "spi")) return &clk_spi; if (!strcmp(id, "hsspi")) return &clk_hsspi; if (!strcmp(id, "xtm")) return &clk_xtm; if (!strcmp(id, "periph")) return &clk_periph; if ((BCMCPU_IS_3368() || BCMCPU_IS_6358()) && !strcmp(id, "pcm")) return &clk_pcm; if ((BCMCPU_IS_6362() || BCMCPU_IS_6368()) && !strcmp(id, "ipsec")) return &clk_ipsec; if ((BCMCPU_IS_6328() || BCMCPU_IS_6362()) && !strcmp(id, "pcie")) return &clk_pcie; return ERR_PTR(-ENOENT); } EXPORT_SYMBOL(clk_get); void clk_put(struct clk *clk) { } EXPORT_SYMBOL(clk_put); #define HSSPI_PLL_HZ_6328 133333333 #define HSSPI_PLL_HZ_6362 400000000 static int __init bcm63xx_clk_init(void) { switch (bcm63xx_get_cpu_id()) { case BCM6328_CPU_ID: clk_hsspi.rate = HSSPI_PLL_HZ_6328; break; case BCM6362_CPU_ID: clk_hsspi.rate = HSSPI_PLL_HZ_6362; break; } return 0; } arch_initcall(bcm63xx_clk_init);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
You can’t perform that action at this time.