[ARM] 3959/1: AT91: Support for SAM9 USB and HCK clocks

The bits used to select the USB clocks are different on the SAM9's.
Add support for the HCK clocks on the AT91SAM9261.

Patch from Patrice Vilchez & Nicolas Ferre

Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Andrew Victor and committed by
Russell King
d481f864 fcc63716

+33 -7
+22 -4
arch/arm/mach-at91rm9200/clock.c
··· 29 29 30 30 #include <asm/hardware.h> 31 31 #include <asm/arch/at91_pmc.h> 32 + #include <asm/arch/cpu.h> 32 33 33 34 #include "clock.h" 34 35 ··· 43 42 #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) 44 43 #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) 45 44 #define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) 45 + #define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) 46 46 47 47 48 48 static LIST_HEAD(clocks); ··· 117 115 static struct clk udpck = { 118 116 .name = "udpck", 119 117 .parent = &pllb, 120 - .pmc_mask = AT91_PMC_UDP, 121 118 .mode = pmc_sys_mode, 122 119 }; 123 120 static struct clk uhpck = { 124 121 .name = "uhpck", 125 122 .parent = &pllb, 126 - .pmc_mask = AT91_PMC_UHP, 127 123 .mode = pmc_sys_mode, 128 124 }; 129 125 ··· 435 435 clk->mode = pmc_periph_mode; 436 436 list_add_tail(&clk->node, &clocks); 437 437 } 438 + else if (clk_is_sys(clk)) { 439 + clk->parent = &mck; 440 + clk->mode = pmc_sys_mode; 441 + 442 + list_add_tail(&clk->node, &clocks); 443 + } 438 444 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS 439 445 else if (clk_is_programmable(clk)) { 440 446 clk->mode = pmc_sys_mode; ··· 593 587 */ 594 588 at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; 595 589 pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); 596 - at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP | AT91_PMC_UDP); 590 + if (cpu_is_at91rm9200()) { 591 + uhpck.pmc_mask = AT91RM9200_PMC_UHP; 592 + udpck.pmc_mask = AT91RM9200_PMC_UDP; 593 + at91_sys_write(AT91_PMC_SCDR, AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP); 594 + at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); 595 + } else if (cpu_is_at91sam9260()) { 596 + uhpck.pmc_mask = AT91SAM926x_PMC_UHP; 597 + udpck.pmc_mask = AT91SAM926x_PMC_UDP; 598 + at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP); 599 + } else if (cpu_is_at91sam9261()) { 600 + uhpck.pmc_mask = (AT91SAM926x_PMC_UHP | AT91_PMC_HCK0); 601 + udpck.pmc_mask = AT91SAM926x_PMC_UDP; 602 + at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91_PMC_HCK0 | AT91SAM926x_PMC_UDP); 603 + } 597 604 at91_sys_write(AT91_CKGR_PLLBR, 0); 598 - at91_sys_write(AT91_PMC_SCER, AT91_PMC_MCKUDP); 599 605 600 606 udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); 601 607 uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+1
arch/arm/mach-at91rm9200/clock.h
··· 10 10 #define CLK_TYPE_PLL 0x2 11 11 #define CLK_TYPE_PROGRAMMABLE 0x4 12 12 #define CLK_TYPE_PERIPHERAL 0x8 13 + #define CLK_TYPE_SYSTEM 0x10 13 14 14 15 15 16 struct clk {
+10 -3
arch/arm/mach-at91rm9200/pm.c
··· 29 29 #include <asm/arch/at91_pmc.h> 30 30 #include <asm/arch/at91rm9200_mc.h> 31 31 #include <asm/arch/gpio.h> 32 + #include <asm/arch/cpu.h> 32 33 33 34 #include "generic.h" 34 35 ··· 71 70 scsr = at91_sys_read(AT91_PMC_SCSR); 72 71 73 72 /* USB must not be using PLLB */ 74 - if ((scsr & (AT91_PMC_UHP | AT91_PMC_UDP)) != 0) { 75 - pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); 76 - return 0; 73 + if (cpu_is_at91rm9200()) { 74 + if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { 75 + pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); 76 + return 0; 77 + } 78 + } else if (cpu_is_at91sam9260()) { 79 + #warning "Check SAM9260 USB clocks" 80 + } else if (cpu_is_at91sam9261()) { 81 + #warning "Check SAM9261 USB clocks" 77 82 } 78 83 79 84 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS