Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 81423
b: refs/heads/master
c: c8004a2
h: refs/heads/master
i:
  81421: 158b462
  81419: 3bab493
  81415: c3d592e
  81407: 3b11ce1
v: v3
  • Loading branch information
Grant Likely committed Jan 26, 2008
1 parent 1b07fa6 commit 0bdd768
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 94d2dde738a50124d1f1b1b40bd5b9d0ed22e2e2
refs/heads/master: c8004a28186110657aa3e75135a6b96ebfa3e8f0
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/platforms/52xx/efika.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ static void __init efika_setup_arch(void)
{
rtas_initialize();

/* Map important registers from the internal memory map */
mpc52xx_map_common_devices();

efika_pcisetup();

#ifdef CONFIG_PM
Expand Down
10 changes: 5 additions & 5 deletions trunk/arch/powerpc/platforms/52xx/lite5200.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,15 @@ static void __init lite5200_setup_arch(void)
if (ppc_md.progress)
ppc_md.progress("lite5200_setup_arch()", 0);

/* Fix things that firmware should have done. */
lite5200_fix_clock_config();
lite5200_fix_port_config();
/* Map important registers from the internal memory map */
mpc52xx_map_common_devices();

/* Some mpc5200 & mpc5200b related configuration */
mpc5200_setup_xlb_arbiter();

/* Map wdt for mpc52xx_restart() */
mpc52xx_map_wdt();
/* Fix things that firmware should have done. */
lite5200_fix_clock_config();
lite5200_fix_port_config();

#ifdef CONFIG_PM
mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
Expand Down
6 changes: 3 additions & 3 deletions trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ static void __init mpc5200_simple_setup_arch(void)
if (ppc_md.progress)
ppc_md.progress("mpc5200_simple_setup_arch()", 0);

/* Map important registers from the internal memory map */
mpc52xx_map_common_devices();

/* Some mpc5200 & mpc5200b related configuration */
mpc5200_setup_xlb_arbiter();

/* Map wdt for mpc52xx_restart() */
mpc52xx_map_wdt();

mpc52xx_setup_pci();
}

Expand Down
65 changes: 61 additions & 4 deletions trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#undef DEBUG

#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/of_platform.h>
#include <asm/io.h>
#include <asm/prom.h>
Expand Down Expand Up @@ -41,7 +42,9 @@ static struct of_device_id mpc52xx_bus_ids[] __initdata = {
* from interrupt context while node mapping (which calls ioremap())
* cannot be used at such point.
*/
static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL;
static spinlock_t mpc52xx_lock = SPIN_LOCK_UNLOCKED;
static struct mpc52xx_gpt __iomem *mpc52xx_wdt;
static struct mpc52xx_cdm __iomem *mpc52xx_cdm;

/**
* mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
Expand Down Expand Up @@ -120,18 +123,27 @@ mpc52xx_declare_of_platform_devices(void)
}

/*
* match tables used by mpc52xx_map_wdt()
* match tables used by mpc52xx_map_common_devices()
*/
static struct of_device_id mpc52xx_gpt_ids[] __initdata = {
{ .compatible = "fsl,mpc5200-gpt", },
{ .compatible = "mpc5200-gpt", }, /* old */
{}
};
static struct of_device_id mpc52xx_cdm_ids[] __initdata = {
{ .compatible = "fsl,mpc5200-cdm", },
{ .compatible = "mpc5200-cdm", }, /* old */
{}
};

/**
* mpc52xx_map_common_devices: iomap devices required by common code
*/
void __init
mpc52xx_map_wdt(void)
mpc52xx_map_common_devices(void)
{
struct device_node *np;

/* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
* possibly from a interrupt context. wdt is only implement
* on a gpt0, so check has-wdt property before mapping.
Expand All @@ -141,11 +153,56 @@ mpc52xx_map_wdt(void)
of_get_property(np, "has-wdt", NULL)) {
mpc52xx_wdt = of_iomap(np, 0);
of_node_put(np);
return;
break;
}
}

/* Clock Distribution Module, used by PSC clock setting function */
np = of_find_matching_node(NULL, mpc52xx_cdm_ids);
mpc52xx_cdm = of_iomap(np, 0);
of_node_put(np);
}

/**
* mpc52xx_set_psc_clkdiv: Set clock divider in the CDM for PSC ports
*
* @psc_id: id of psc port; must be 1,2,3 or 6
* @clkdiv: clock divider value to put into CDM PSC register.
*/
int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
{
unsigned long flags;
u16 __iomem *reg;
u32 val;
u32 mask;
u32 mclken_div;

if (!mpc52xx_cdm)
return -ENODEV;

mclken_div = 0x8000 | (clkdiv & 0x1FF);
switch (psc_id) {
case 1: reg = &mpc52xx_cdm->mclken_div_psc1; mask = 0x20; break;
case 2: reg = &mpc52xx_cdm->mclken_div_psc2; mask = 0x40; break;
case 3: reg = &mpc52xx_cdm->mclken_div_psc3; mask = 0x80; break;
case 6: reg = &mpc52xx_cdm->mclken_div_psc6; mask = 0x10; break;
default:
return -ENODEV;
}

/* Set the rate and enable the clock */
spin_lock_irqsave(&mpc52xx_lock, flags);
out_be16(reg, mclken_div);
val = in_be32(&mpc52xx_cdm->clk_enables);
out_be32(&mpc52xx_cdm->clk_enables, val | mask);
spin_unlock_irqrestore(&mpc52xx_lock, flags);

return 0;
}

/**
* mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
*/
void
mpc52xx_restart(char *cmd)
{
Expand Down
36 changes: 36 additions & 0 deletions trunk/arch/ppc/syslib/mpc52xx_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/


#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/time.h>
#include <asm/mpc52xx.h>
Expand Down Expand Up @@ -275,3 +276,38 @@ int mpc52xx_match_psc_function(int psc_idx, const char *func)

return 0;
}

int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
{
static spinlock_t lock = SPIN_LOCK_UNLOCKED;
struct mpc52xx_cdm __iomem *cdm;
unsigned long flags;
u16 mclken_div;
u16 __iomem *reg;
u32 mask;

cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
if (!cdm) {
printk(KERN_ERR __FILE__ ": Error mapping CDM\n");
return -ENODEV;
}

mclken_div = 0x8000 | (clkdiv & 0x1FF);
switch (psc_id) {
case 1: reg = &cdm->mclken_div_psc1; mask = 0x20; break;
case 2: reg = &cdm->mclken_div_psc2; mask = 0x40; break;
case 3: reg = &cdm->mclken_div_psc3; mask = 0x80; break;
case 6: reg = &cdm->mclken_div_psc6; mask = 0x10; break;
default:
return -ENODEV;
}

/* Set the rate and enable the clock */
spin_lock_irqsave(&lock, flags);
out_be16(reg, mclken_div);
out_be32(&cdm->clk_enables, in_be32(&cdm->clk_enables) | mask);
spin_unlock_irqrestore(&lock, flags);

iounmap(cdm);
return 0;
}
9 changes: 6 additions & 3 deletions trunk/include/asm-powerpc/mpc52xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,23 +248,26 @@ struct mpc52xx_cdm {

#ifndef __ASSEMBLY__

/* mpc52xx_common.c */
extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node);
extern void mpc5200_setup_xlb_arbiter(void);
extern void mpc52xx_declare_of_platform_devices(void);
extern void mpc52xx_map_common_devices(void);
extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
extern void mpc52xx_restart(char *cmd);

/* mpc52xx_pic.c */
extern void mpc52xx_init_irq(void);
extern unsigned int mpc52xx_get_irq(void);

/* mpc52xx_pci.c */
#ifdef CONFIG_PCI
extern int __init mpc52xx_add_bridge(struct device_node *node);
extern void __init mpc52xx_setup_pci(void);
#else
static inline void mpc52xx_setup_pci(void) { }
#endif

extern void __init mpc52xx_map_wdt(void);
extern void mpc52xx_restart(char *cmd);

#endif /* __ASSEMBLY__ */

#ifdef CONFIG_PM
Expand Down

0 comments on commit 0bdd768

Please sign in to comment.