diff options
| author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-08-08 21:23:58 -0400 |
|---|---|---|
| committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-08-08 21:23:58 -0400 |
| commit | 8b449d1f1371e8ecd0b2499034e0b1432cdbe662 (patch) | |
| tree | 56b203189ef65d853f1355abfc65263d96e44a06 | |
| parent | 2ed9aae0facd603f9f9b8347d1d7e9de23bde286 (diff) | |
| parent | ee110066130b79b7abf63bbd836d382699252b81 (diff) | |
Merge remote branch 'gcl/next' into next
| -rw-r--r-- | arch/powerpc/include/asm/mpc52xx.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/mpc52xx_psc.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/kernel/setup-common.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/52xx/mpc52xx_common.c | 106 | ||||
| -rw-r--r-- | sound/soc/fsl/mpc5200_psc_ac97.c | 22 |
5 files changed, 128 insertions, 4 deletions
diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h index b664ce79a172..1f41382eda38 100644 --- a/arch/powerpc/include/asm/mpc52xx.h +++ b/arch/powerpc/include/asm/mpc52xx.h | |||
| @@ -271,6 +271,7 @@ struct mpc52xx_intr { | |||
| 271 | /* mpc52xx_common.c */ | 271 | /* mpc52xx_common.c */ |
| 272 | extern void mpc5200_setup_xlb_arbiter(void); | 272 | extern void mpc5200_setup_xlb_arbiter(void); |
| 273 | extern void mpc52xx_declare_of_platform_devices(void); | 273 | extern void mpc52xx_declare_of_platform_devices(void); |
| 274 | extern int mpc5200_psc_ac97_gpio_reset(int psc_number); | ||
| 274 | extern void mpc52xx_map_common_devices(void); | 275 | extern void mpc52xx_map_common_devices(void); |
| 275 | extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); | 276 | extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); |
| 276 | extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); | 277 | extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); |
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h index ecc4fc69ac13..2966df604221 100644 --- a/arch/powerpc/include/asm/mpc52xx_psc.h +++ b/arch/powerpc/include/asm/mpc52xx_psc.h | |||
| @@ -131,6 +131,7 @@ | |||
| 131 | #define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24) | 131 | #define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24) |
| 132 | #define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24) | 132 | #define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24) |
| 133 | #define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24) | 133 | #define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24) |
| 134 | #define MPC52xx_PSC_SICR_ACRB (0x8 << 24) | ||
| 134 | #define MPC52xx_PSC_SICR_AWR (1 << 30) | 135 | #define MPC52xx_PSC_SICR_AWR (1 << 30) |
| 135 | #define MPC52xx_PSC_SICR_GENCLK (1 << 23) | 136 | #define MPC52xx_PSC_SICR_GENCLK (1 << 23) |
| 136 | #define MPC52xx_PSC_SICR_I2S (1 << 22) | 137 | #define MPC52xx_PSC_SICR_I2S (1 << 22) |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 15ade0d7bbb2..9d4882a46647 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
| @@ -96,7 +96,9 @@ struct screen_info screen_info = { | |||
| 96 | 96 | ||
| 97 | /* Variables required to store legacy IO irq routing */ | 97 | /* Variables required to store legacy IO irq routing */ |
| 98 | int of_i8042_kbd_irq; | 98 | int of_i8042_kbd_irq; |
| 99 | EXPORT_SYMBOL_GPL(of_i8042_kbd_irq); | ||
| 99 | int of_i8042_aux_irq; | 100 | int of_i8042_aux_irq; |
| 101 | EXPORT_SYMBOL_GPL(of_i8042_aux_irq); | ||
| 100 | 102 | ||
| 101 | #ifdef __DO_IRQ_CANON | 103 | #ifdef __DO_IRQ_CANON |
| 102 | /* XXX should go elsewhere eventually */ | 104 | /* XXX should go elsewhere eventually */ |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index a46bad0c2339..6e905314ad5d 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c | |||
| @@ -12,9 +12,11 @@ | |||
| 12 | 12 | ||
| 13 | #undef DEBUG | 13 | #undef DEBUG |
| 14 | 14 | ||
| 15 | #include <linux/gpio.h> | ||
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 16 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
| 17 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
| 19 | #include <linux/of_gpio.h> | ||
| 18 | #include <asm/io.h> | 20 | #include <asm/io.h> |
| 19 | #include <asm/prom.h> | 21 | #include <asm/prom.h> |
| 20 | #include <asm/mpc52xx.h> | 22 | #include <asm/mpc52xx.h> |
| @@ -82,6 +84,14 @@ mpc5200_setup_xlb_arbiter(void) | |||
| 82 | iounmap(xlb); | 84 | iounmap(xlb); |
| 83 | } | 85 | } |
| 84 | 86 | ||
| 87 | /* | ||
| 88 | * This variable is mapped in mpc52xx_map_common_devices and | ||
| 89 | * used in mpc5200_psc_ac97_gpio_reset(). | ||
| 90 | */ | ||
| 91 | static DEFINE_SPINLOCK(gpio_lock); | ||
| 92 | struct mpc52xx_gpio __iomem *simple_gpio; | ||
| 93 | struct mpc52xx_gpio_wkup __iomem *wkup_gpio; | ||
| 94 | |||
| 85 | /** | 95 | /** |
| 86 | * mpc52xx_declare_of_platform_devices: register internal devices and children | 96 | * mpc52xx_declare_of_platform_devices: register internal devices and children |
| 87 | * of the localplus bus to the of_platform | 97 | * of the localplus bus to the of_platform |
| @@ -109,6 +119,15 @@ static struct of_device_id mpc52xx_cdm_ids[] __initdata = { | |||
| 109 | { .compatible = "mpc5200-cdm", }, /* old */ | 119 | { .compatible = "mpc5200-cdm", }, /* old */ |
| 110 | {} | 120 | {} |
| 111 | }; | 121 | }; |
| 122 | static const struct of_device_id mpc52xx_gpio_simple[] = { | ||
| 123 | { .compatible = "fsl,mpc5200-gpio", }, | ||
| 124 | {} | ||
| 125 | }; | ||
| 126 | static const struct of_device_id mpc52xx_gpio_wkup[] = { | ||
| 127 | { .compatible = "fsl,mpc5200-gpio-wkup", }, | ||
| 128 | {} | ||
| 129 | }; | ||
| 130 | |||
| 112 | 131 | ||
| 113 | /** | 132 | /** |
| 114 | * mpc52xx_map_common_devices: iomap devices required by common code | 133 | * mpc52xx_map_common_devices: iomap devices required by common code |
| @@ -135,6 +154,16 @@ mpc52xx_map_common_devices(void) | |||
| 135 | np = of_find_matching_node(NULL, mpc52xx_cdm_ids); | 154 | np = of_find_matching_node(NULL, mpc52xx_cdm_ids); |
| 136 | mpc52xx_cdm = of_iomap(np, 0); | 155 | mpc52xx_cdm = of_iomap(np, 0); |
| 137 | of_node_put(np); | 156 | of_node_put(np); |
| 157 | |||
| 158 | /* simple_gpio registers */ | ||
| 159 | np = of_find_matching_node(NULL, mpc52xx_gpio_simple); | ||
| 160 | simple_gpio = of_iomap(np, 0); | ||
| 161 | of_node_put(np); | ||
| 162 | |||
| 163 | /* wkup_gpio registers */ | ||
| 164 | np = of_find_matching_node(NULL, mpc52xx_gpio_wkup); | ||
| 165 | wkup_gpio = of_iomap(np, 0); | ||
| 166 | of_node_put(np); | ||
| 138 | } | 167 | } |
| 139 | 168 | ||
| 140 | /** | 169 | /** |
| @@ -233,3 +262,80 @@ mpc52xx_restart(char *cmd) | |||
| 233 | 262 | ||
| 234 | while (1); | 263 | while (1); |
| 235 | } | 264 | } |
| 265 | |||
| 266 | #define PSC1_RESET 0x1 | ||
| 267 | #define PSC1_SYNC 0x4 | ||
| 268 | #define PSC1_SDATA_OUT 0x1 | ||
| 269 | #define PSC2_RESET 0x2 | ||
| 270 | #define PSC2_SYNC (0x4<<4) | ||
| 271 | #define PSC2_SDATA_OUT (0x1<<4) | ||
| 272 | #define MPC52xx_GPIO_PSC1_MASK 0x7 | ||
| 273 | #define MPC52xx_GPIO_PSC2_MASK (0x7<<4) | ||
| 274 | |||
| 275 | /** | ||
| 276 | * mpc5200_psc_ac97_gpio_reset: Use gpio pins to reset the ac97 bus | ||
| 277 | * | ||
| 278 | * @psc: psc number to reset (only psc 1 and 2 support ac97) | ||
| 279 | */ | ||
| 280 | int mpc5200_psc_ac97_gpio_reset(int psc_number) | ||
| 281 | { | ||
| 282 | unsigned long flags; | ||
| 283 | u32 gpio; | ||
| 284 | u32 mux; | ||
| 285 | int out; | ||
| 286 | int reset; | ||
| 287 | int sync; | ||
| 288 | |||
| 289 | if ((!simple_gpio) || (!wkup_gpio)) | ||
| 290 | return -ENODEV; | ||
| 291 | |||
| 292 | switch (psc_number) { | ||
| 293 | case 0: | ||
| 294 | reset = PSC1_RESET; /* AC97_1_RES */ | ||
| 295 | sync = PSC1_SYNC; /* AC97_1_SYNC */ | ||
| 296 | out = PSC1_SDATA_OUT; /* AC97_1_SDATA_OUT */ | ||
| 297 | gpio = MPC52xx_GPIO_PSC1_MASK; | ||
| 298 | break; | ||
| 299 | case 1: | ||
| 300 | reset = PSC2_RESET; /* AC97_2_RES */ | ||
| 301 | sync = PSC2_SYNC; /* AC97_2_SYNC */ | ||
| 302 | out = PSC2_SDATA_OUT; /* AC97_2_SDATA_OUT */ | ||
| 303 | gpio = MPC52xx_GPIO_PSC2_MASK; | ||
| 304 | break; | ||
| 305 | default: | ||
| 306 | pr_err(__FILE__ ": Unable to determine PSC, no ac97 " | ||
| 307 | "cold-reset will be performed\n"); | ||
| 308 | return -ENODEV; | ||
| 309 | } | ||
| 310 | |||
| 311 | spin_lock_irqsave(&gpio_lock, flags); | ||
| 312 | |||
| 313 | /* Reconfiure pin-muxing to gpio */ | ||
| 314 | mux = in_be32(&simple_gpio->port_config); | ||
| 315 | out_be32(&simple_gpio->port_config, mux & (~gpio)); | ||
| 316 | |||
| 317 | /* enable gpio pins for output */ | ||
| 318 | setbits8(&wkup_gpio->wkup_gpioe, reset); | ||
| 319 | setbits32(&simple_gpio->simple_gpioe, sync | out); | ||
| 320 | |||
| 321 | setbits8(&wkup_gpio->wkup_ddr, reset); | ||
| 322 | setbits32(&simple_gpio->simple_ddr, sync | out); | ||
| 323 | |||
| 324 | /* Assert cold reset */ | ||
| 325 | clrbits32(&simple_gpio->simple_dvo, sync | out); | ||
| 326 | clrbits8(&wkup_gpio->wkup_dvo, reset); | ||
| 327 | |||
| 328 | /* wait at lease 1 us */ | ||
| 329 | udelay(2); | ||
| 330 | |||
| 331 | /* Deassert reset */ | ||
| 332 | setbits8(&wkup_gpio->wkup_dvo, reset); | ||
| 333 | |||
| 334 | /* Restore pin-muxing */ | ||
| 335 | out_be32(&simple_gpio->port_config, mux); | ||
| 336 | |||
| 337 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
| 338 | |||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | EXPORT_SYMBOL(mpc5200_psc_ac97_gpio_reset); | ||
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index e2ee220bfb7e..e7f5d50ed084 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | #include <asm/time.h> | 21 | #include <asm/time.h> |
| 22 | #include <asm/delay.h> | 22 | #include <asm/delay.h> |
| 23 | #include <asm/mpc52xx.h> | ||
| 23 | #include <asm/mpc52xx_psc.h> | 24 | #include <asm/mpc52xx_psc.h> |
| 24 | 25 | ||
| 25 | #include "mpc5200_dma.h" | 26 | #include "mpc5200_dma.h" |
| @@ -100,19 +101,32 @@ static void psc_ac97_warm_reset(struct snd_ac97 *ac97) | |||
| 100 | { | 101 | { |
| 101 | struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; | 102 | struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; |
| 102 | 103 | ||
| 104 | mutex_lock(&psc_dma->mutex); | ||
| 105 | |||
| 103 | out_be32(®s->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR); | 106 | out_be32(®s->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR); |
| 104 | udelay(3); | 107 | udelay(3); |
| 105 | out_be32(®s->sicr, psc_dma->sicr); | 108 | out_be32(®s->sicr, psc_dma->sicr); |
| 109 | |||
| 110 | mutex_unlock(&psc_dma->mutex); | ||
| 106 | } | 111 | } |
| 107 | 112 | ||
| 108 | static void psc_ac97_cold_reset(struct snd_ac97 *ac97) | 113 | static void psc_ac97_cold_reset(struct snd_ac97 *ac97) |
| 109 | { | 114 | { |
| 110 | struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; | 115 | struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; |
| 111 | 116 | ||
| 112 | /* Do a cold reset */ | 117 | mutex_lock(&psc_dma->mutex); |
| 113 | out_8(®s->op1, MPC52xx_PSC_OP_RES); | 118 | dev_dbg(psc_dma->dev, "cold reset\n"); |
| 114 | udelay(10); | 119 | |
| 115 | out_8(®s->op0, MPC52xx_PSC_OP_RES); | 120 | mpc5200_psc_ac97_gpio_reset(psc_dma->id); |
| 121 | |||
| 122 | /* Notify the PSC that a reset has occurred */ | ||
| 123 | out_be32(®s->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_ACRB); | ||
| 124 | |||
| 125 | /* Re-enable RX and TX */ | ||
| 126 | out_8(®s->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); | ||
| 127 | |||
| 128 | mutex_unlock(&psc_dma->mutex); | ||
| 129 | |||
| 116 | msleep(1); | 130 | msleep(1); |
| 117 | psc_ac97_warm_reset(ac97); | 131 | psc_ac97_warm_reset(ac97); |
| 118 | } | 132 | } |
