0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #undef DEBUG
0014
0015 #include <linux/gpio.h>
0016 #include <linux/kernel.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/of_address.h>
0019 #include <linux/of_platform.h>
0020 #include <linux/of_gpio.h>
0021 #include <linux/export.h>
0022 #include <asm/io.h>
0023 #include <asm/mpc52xx.h>
0024
0025
0026 static const struct of_device_id mpc52xx_xlb_ids[] __initconst = {
0027 { .compatible = "fsl,mpc5200-xlb", },
0028 { .compatible = "mpc5200-xlb", },
0029 {}
0030 };
0031 static const struct of_device_id mpc52xx_bus_ids[] __initconst = {
0032 { .compatible = "fsl,mpc5200-immr", },
0033 { .compatible = "fsl,mpc5200b-immr", },
0034 { .compatible = "simple-bus", },
0035
0036
0037 { .compatible = "fsl,lpb", },
0038 { .type = "builtin", .compatible = "mpc5200", },
0039 { .type = "soc", .compatible = "mpc5200", },
0040 {}
0041 };
0042
0043
0044
0045
0046
0047
0048
0049 static DEFINE_SPINLOCK(mpc52xx_lock);
0050 static struct mpc52xx_gpt __iomem *mpc52xx_wdt;
0051 static struct mpc52xx_cdm __iomem *mpc52xx_cdm;
0052
0053
0054
0055
0056 void __init
0057 mpc5200_setup_xlb_arbiter(void)
0058 {
0059 struct device_node *np;
0060 struct mpc52xx_xlb __iomem *xlb;
0061
0062 np = of_find_matching_node(NULL, mpc52xx_xlb_ids);
0063 xlb = of_iomap(np, 0);
0064 of_node_put(np);
0065 if (!xlb) {
0066 printk(KERN_ERR __FILE__ ": "
0067 "Error mapping XLB in mpc52xx_setup_cpu(). "
0068 "Expect some abnormal behavior\n");
0069 return;
0070 }
0071
0072
0073 out_be32(&xlb->master_pri_enable, 0xff);
0074 out_be32(&xlb->master_priority, 0x11111111);
0075
0076
0077
0078
0079
0080
0081
0082 if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR)
0083 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
0084
0085 iounmap(xlb);
0086 }
0087
0088
0089
0090
0091
0092 static DEFINE_SPINLOCK(gpio_lock);
0093 struct mpc52xx_gpio __iomem *simple_gpio;
0094 struct mpc52xx_gpio_wkup __iomem *wkup_gpio;
0095
0096
0097
0098
0099
0100
0101 void __init mpc52xx_declare_of_platform_devices(void)
0102 {
0103
0104 if (of_platform_populate(NULL, mpc52xx_bus_ids, NULL, NULL))
0105 pr_err(__FILE__ ": Error while populating devices from DT\n");
0106 }
0107
0108
0109
0110
0111 static const struct of_device_id mpc52xx_gpt_ids[] __initconst = {
0112 { .compatible = "fsl,mpc5200-gpt", },
0113 { .compatible = "mpc5200-gpt", },
0114 {}
0115 };
0116 static const struct of_device_id mpc52xx_cdm_ids[] __initconst = {
0117 { .compatible = "fsl,mpc5200-cdm", },
0118 { .compatible = "mpc5200-cdm", },
0119 {}
0120 };
0121 static const struct of_device_id mpc52xx_gpio_simple[] __initconst = {
0122 { .compatible = "fsl,mpc5200-gpio", },
0123 {}
0124 };
0125 static const struct of_device_id mpc52xx_gpio_wkup[] __initconst = {
0126 { .compatible = "fsl,mpc5200-gpio-wkup", },
0127 {}
0128 };
0129
0130
0131
0132
0133
0134 void __init
0135 mpc52xx_map_common_devices(void)
0136 {
0137 struct device_node *np;
0138
0139
0140
0141
0142
0143 for_each_matching_node(np, mpc52xx_gpt_ids) {
0144 if (of_get_property(np, "fsl,has-wdt", NULL) ||
0145 of_get_property(np, "has-wdt", NULL)) {
0146 mpc52xx_wdt = of_iomap(np, 0);
0147 of_node_put(np);
0148 break;
0149 }
0150 }
0151
0152
0153 np = of_find_matching_node(NULL, mpc52xx_cdm_ids);
0154 mpc52xx_cdm = of_iomap(np, 0);
0155 of_node_put(np);
0156
0157
0158 np = of_find_matching_node(NULL, mpc52xx_gpio_simple);
0159 simple_gpio = of_iomap(np, 0);
0160 of_node_put(np);
0161
0162
0163 np = of_find_matching_node(NULL, mpc52xx_gpio_wkup);
0164 wkup_gpio = of_iomap(np, 0);
0165 of_node_put(np);
0166 }
0167
0168
0169
0170
0171
0172
0173
0174 int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
0175 {
0176 unsigned long flags;
0177 u16 __iomem *reg;
0178 u32 val;
0179 u32 mask;
0180 u32 mclken_div;
0181
0182 if (!mpc52xx_cdm)
0183 return -ENODEV;
0184
0185 mclken_div = 0x8000 | (clkdiv & 0x1FF);
0186 switch (psc_id) {
0187 case 1: reg = &mpc52xx_cdm->mclken_div_psc1; mask = 0x20; break;
0188 case 2: reg = &mpc52xx_cdm->mclken_div_psc2; mask = 0x40; break;
0189 case 3: reg = &mpc52xx_cdm->mclken_div_psc3; mask = 0x80; break;
0190 case 6: reg = &mpc52xx_cdm->mclken_div_psc6; mask = 0x10; break;
0191 default:
0192 return -ENODEV;
0193 }
0194
0195
0196 spin_lock_irqsave(&mpc52xx_lock, flags);
0197 out_be16(reg, mclken_div);
0198 val = in_be32(&mpc52xx_cdm->clk_enables);
0199 out_be32(&mpc52xx_cdm->clk_enables, val | mask);
0200 spin_unlock_irqrestore(&mpc52xx_lock, flags);
0201
0202 return 0;
0203 }
0204 EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv);
0205
0206
0207
0208
0209 void __noreturn mpc52xx_restart(char *cmd)
0210 {
0211 local_irq_disable();
0212
0213
0214
0215 if (mpc52xx_wdt) {
0216 out_be32(&mpc52xx_wdt->mode, 0x00000000);
0217 out_be32(&mpc52xx_wdt->count, 0x000000ff);
0218 out_be32(&mpc52xx_wdt->mode, 0x00009004);
0219 } else
0220 printk(KERN_ERR __FILE__ ": "
0221 "mpc52xx_restart: Can't access wdt. "
0222 "Restart impossible, system halted.\n");
0223
0224 while (1);
0225 }
0226
0227 #define PSC1_RESET 0x1
0228 #define PSC1_SYNC 0x4
0229 #define PSC1_SDATA_OUT 0x1
0230 #define PSC2_RESET 0x2
0231 #define PSC2_SYNC (0x4<<4)
0232 #define PSC2_SDATA_OUT (0x1<<4)
0233 #define MPC52xx_GPIO_PSC1_MASK 0x7
0234 #define MPC52xx_GPIO_PSC2_MASK (0x7<<4)
0235
0236
0237
0238
0239
0240
0241 int mpc5200_psc_ac97_gpio_reset(int psc_number)
0242 {
0243 unsigned long flags;
0244 u32 gpio;
0245 u32 mux;
0246 int out;
0247 int reset;
0248 int sync;
0249
0250 if ((!simple_gpio) || (!wkup_gpio))
0251 return -ENODEV;
0252
0253 switch (psc_number) {
0254 case 0:
0255 reset = PSC1_RESET;
0256 sync = PSC1_SYNC;
0257 out = PSC1_SDATA_OUT;
0258 gpio = MPC52xx_GPIO_PSC1_MASK;
0259 break;
0260 case 1:
0261 reset = PSC2_RESET;
0262 sync = PSC2_SYNC;
0263 out = PSC2_SDATA_OUT;
0264 gpio = MPC52xx_GPIO_PSC2_MASK;
0265 break;
0266 default:
0267 pr_err(__FILE__ ": Unable to determine PSC, no ac97 "
0268 "cold-reset will be performed\n");
0269 return -ENODEV;
0270 }
0271
0272 spin_lock_irqsave(&gpio_lock, flags);
0273
0274
0275 mux = in_be32(&simple_gpio->port_config);
0276 out_be32(&simple_gpio->port_config, mux & (~gpio));
0277
0278
0279 setbits8(&wkup_gpio->wkup_gpioe, reset);
0280 setbits32(&simple_gpio->simple_gpioe, sync | out);
0281
0282 setbits8(&wkup_gpio->wkup_ddr, reset);
0283 setbits32(&simple_gpio->simple_ddr, sync | out);
0284
0285
0286 clrbits32(&simple_gpio->simple_dvo, sync | out);
0287 clrbits8(&wkup_gpio->wkup_dvo, reset);
0288
0289
0290 udelay(1);
0291
0292
0293 setbits8(&wkup_gpio->wkup_dvo, reset);
0294
0295
0296
0297 __delay(7);
0298
0299
0300 out_be32(&simple_gpio->port_config, mux);
0301
0302 spin_unlock_irqrestore(&gpio_lock, flags);
0303
0304 return 0;
0305 }
0306 EXPORT_SYMBOL(mpc5200_psc_ac97_gpio_reset);