0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/fsl/guts.h>
0020 #include <linux/pci.h>
0021 #include <linux/of_address.h>
0022 #include <linux/of_platform.h>
0023 #include <asm/div64.h>
0024 #include <asm/mpic.h>
0025 #include <asm/swiotlb.h>
0026
0027 #include <sysdev/fsl_soc.h>
0028 #include <sysdev/fsl_pci.h>
0029 #include <asm/udbg.h>
0030 #include <asm/fsl_lbc.h>
0031 #include "smp.h"
0032
0033 #include "mpc85xx.h"
0034
0035 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
0036
0037 #define PMUXCR_ELBCDIU_MASK 0xc0000000
0038 #define PMUXCR_ELBCDIU_NOR16 0x80000000
0039 #define PMUXCR_ELBCDIU_DIU 0x40000000
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 #define CLKDVDR_PXCKEN 0x80000000
0053 #define CLKDVDR_PXCKINV 0x10000000
0054 #define CLKDVDR_PXCKDLY 0x06000000
0055 #define CLKDVDR_PXCLK_MASK 0x00FF0000
0056
0057
0058 #define PX_CTL 3
0059 #define PX_BRDCFG0 8
0060 #define PX_BRDCFG1 9
0061
0062 #define PX_BRDCFG0_ELBC_SPI_MASK 0xc0
0063 #define PX_BRDCFG0_ELBC_SPI_ELBC 0x00
0064 #define PX_BRDCFG0_ELBC_SPI_NULL 0xc0
0065 #define PX_BRDCFG0_ELBC_DIU 0x02
0066
0067 #define PX_BRDCFG1_DVIEN 0x80
0068 #define PX_BRDCFG1_DFPEN 0x40
0069 #define PX_BRDCFG1_BACKLIGHT 0x20
0070 #define PX_BRDCFG1_DDCEN 0x10
0071
0072 #define PX_CTL_ALTACC 0x80
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 #define AD_BYTE_F 0x10000000
0083 #define AD_ALPHA_C_MASK 0x0E000000
0084 #define AD_ALPHA_C_SHIFT 25
0085 #define AD_BLUE_C_MASK 0x01800000
0086 #define AD_BLUE_C_SHIFT 23
0087 #define AD_GREEN_C_MASK 0x00600000
0088 #define AD_GREEN_C_SHIFT 21
0089 #define AD_RED_C_MASK 0x00180000
0090 #define AD_RED_C_SHIFT 19
0091 #define AD_PALETTE 0x00040000
0092 #define AD_PIXEL_S_MASK 0x00030000
0093 #define AD_PIXEL_S_SHIFT 16
0094 #define AD_COMP_3_MASK 0x0000F000
0095 #define AD_COMP_3_SHIFT 12
0096 #define AD_COMP_2_MASK 0x00000F00
0097 #define AD_COMP_2_SHIFT 8
0098 #define AD_COMP_1_MASK 0x000000F0
0099 #define AD_COMP_1_SHIFT 4
0100 #define AD_COMP_0_MASK 0x0000000F
0101 #define AD_COMP_0_SHIFT 0
0102
0103 #define MAKE_AD(alpha, red, blue, green, size, c0, c1, c2, c3) \
0104 cpu_to_le32(AD_BYTE_F | (alpha << AD_ALPHA_C_SHIFT) | \
0105 (blue << AD_BLUE_C_SHIFT) | (green << AD_GREEN_C_SHIFT) | \
0106 (red << AD_RED_C_SHIFT) | (c3 << AD_COMP_3_SHIFT) | \
0107 (c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
0108 (c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
0109
0110 struct fsl_law {
0111 u32 lawbar;
0112 u32 reserved1;
0113 u32 lawar;
0114 u32 reserved[5];
0115 };
0116
0117 #define LAWBAR_MASK 0x00F00000
0118 #define LAWBAR_SHIFT 12
0119
0120 #define LAWAR_EN 0x80000000
0121 #define LAWAR_TGT_MASK 0x01F00000
0122 #define LAW_TRGT_IF_LBC (0x04 << 20)
0123
0124 #define LAWAR_MASK (LAWAR_EN | LAWAR_TGT_MASK)
0125 #define LAWAR_MATCH (LAWAR_EN | LAW_TRGT_IF_LBC)
0126
0127 #define BR_BA 0xFFFF8000
0128
0129
0130
0131
0132
0133
0134
0135
0136 static phys_addr_t lbc_br_to_phys(const void *ecm, unsigned int count, u32 br)
0137 {
0138 #ifndef CONFIG_PHYS_64BIT
0139
0140
0141
0142
0143 return br & BR_BA;
0144 #else
0145 const struct fsl_law *law = ecm + 0xc08;
0146 unsigned int i;
0147
0148 for (i = 0; i < count; i++) {
0149 u64 lawbar = in_be32(&law[i].lawbar);
0150 u32 lawar = in_be32(&law[i].lawar);
0151
0152 if ((lawar & LAWAR_MASK) == LAWAR_MATCH)
0153
0154 return (br & BR_BA) | ((lawbar & LAWBAR_MASK) << 12);
0155 }
0156
0157 return 0;
0158 #endif
0159 }
0160
0161
0162
0163
0164 static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
0165 {
0166 struct device_node *guts_node;
0167 struct device_node *lbc_node = NULL;
0168 struct device_node *law_node = NULL;
0169 struct ccsr_guts __iomem *guts;
0170 struct fsl_lbc_regs *lbc = NULL;
0171 void *ecm = NULL;
0172 u8 __iomem *lbc_lcs0_ba = NULL;
0173 u8 __iomem *lbc_lcs1_ba = NULL;
0174 phys_addr_t cs0_addr, cs1_addr;
0175 u32 br0, or0, br1, or1;
0176 const __be32 *iprop;
0177 unsigned int num_laws;
0178 u8 b;
0179
0180
0181 guts_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
0182 if (!guts_node) {
0183 pr_err("p1022ds: missing global utilities device node\n");
0184 return;
0185 }
0186
0187 guts = of_iomap(guts_node, 0);
0188 if (!guts) {
0189 pr_err("p1022ds: could not map global utilities device\n");
0190 goto exit;
0191 }
0192
0193 lbc_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc");
0194 if (!lbc_node) {
0195 pr_err("p1022ds: missing localbus node\n");
0196 goto exit;
0197 }
0198
0199 lbc = of_iomap(lbc_node, 0);
0200 if (!lbc) {
0201 pr_err("p1022ds: could not map localbus node\n");
0202 goto exit;
0203 }
0204
0205 law_node = of_find_compatible_node(NULL, NULL, "fsl,ecm-law");
0206 if (!law_node) {
0207 pr_err("p1022ds: missing local access window node\n");
0208 goto exit;
0209 }
0210
0211 ecm = of_iomap(law_node, 0);
0212 if (!ecm) {
0213 pr_err("p1022ds: could not map local access window node\n");
0214 goto exit;
0215 }
0216
0217 iprop = of_get_property(law_node, "fsl,num-laws", NULL);
0218 if (!iprop) {
0219 pr_err("p1022ds: LAW node is missing fsl,num-laws property\n");
0220 goto exit;
0221 }
0222 num_laws = be32_to_cpup(iprop);
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 br0 = in_be32(&lbc->bank[0].br);
0235 br1 = in_be32(&lbc->bank[1].br);
0236 or0 = in_be32(&lbc->bank[0].or);
0237 or1 = in_be32(&lbc->bank[1].or);
0238
0239
0240 if (!(br0 & BR_V) || !(br1 & BR_V)) {
0241 pr_err("p1022ds: CS0 and/or CS1 is not programmed\n");
0242 goto exit;
0243 }
0244
0245
0246
0247
0248
0249
0250 if ((br0 & BR_MSEL) != BR_MS_GPCM) {
0251 br0 = (br0 & BR_BA) | BR_V;
0252 or0 = 0xFFFF8000 | 0xFF7;
0253 out_be32(&lbc->bank[0].br, br0);
0254 out_be32(&lbc->bank[0].or, or0);
0255 }
0256 if ((br1 & BR_MSEL) != BR_MS_GPCM) {
0257 br1 = (br1 & BR_BA) | BR_V;
0258 or1 = 0xFFFF8000 | 0xFF7;
0259 out_be32(&lbc->bank[1].br, br1);
0260 out_be32(&lbc->bank[1].or, or1);
0261 }
0262
0263 cs0_addr = lbc_br_to_phys(ecm, num_laws, br0);
0264 if (!cs0_addr) {
0265 pr_err("p1022ds: could not determine physical address for CS0"
0266 " (BR0=%08x)\n", br0);
0267 goto exit;
0268 }
0269 cs1_addr = lbc_br_to_phys(ecm, num_laws, br1);
0270 if (!cs1_addr) {
0271 pr_err("p1022ds: could not determine physical address for CS1"
0272 " (BR1=%08x)\n", br1);
0273 goto exit;
0274 }
0275
0276 lbc_lcs0_ba = ioremap(cs0_addr, 1);
0277 if (!lbc_lcs0_ba) {
0278 pr_err("p1022ds: could not ioremap CS0 address %llx\n",
0279 (unsigned long long)cs0_addr);
0280 goto exit;
0281 }
0282 lbc_lcs1_ba = ioremap(cs1_addr, 1);
0283 if (!lbc_lcs1_ba) {
0284 pr_err("p1022ds: could not ioremap CS1 address %llx\n",
0285 (unsigned long long)cs1_addr);
0286 goto exit;
0287 }
0288
0289
0290 if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
0291 PMUXCR_ELBCDIU_DIU) {
0292 struct device_node *pixis_node;
0293 void __iomem *pixis;
0294
0295 pixis_node =
0296 of_find_compatible_node(NULL, NULL, "fsl,p1022ds-fpga");
0297 if (!pixis_node) {
0298 pr_err("p1022ds: missing pixis node\n");
0299 goto exit;
0300 }
0301
0302 pixis = of_iomap(pixis_node, 0);
0303 of_node_put(pixis_node);
0304 if (!pixis) {
0305 pr_err("p1022ds: could not map pixis registers\n");
0306 goto exit;
0307 }
0308
0309
0310 setbits8(pixis + PX_CTL, PX_CTL_ALTACC);
0311 iounmap(pixis);
0312
0313
0314 out_8(lbc_lcs0_ba, PX_BRDCFG0);
0315 b = in_8(lbc_lcs1_ba);
0316 b |= PX_BRDCFG0_ELBC_DIU;
0317 out_8(lbc_lcs1_ba, b);
0318
0319
0320 clrsetbits_be32(&guts->pmuxcr, PMUXCR_ELBCDIU_MASK,
0321 PMUXCR_ELBCDIU_DIU);
0322 in_be32(&guts->pmuxcr);
0323 }
0324
0325
0326 switch (port) {
0327 case FSL_DIU_PORT_DVI:
0328
0329 out_8(lbc_lcs0_ba, PX_BRDCFG1);
0330 b = in_8(lbc_lcs1_ba);
0331 b &= ~(PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
0332 b |= PX_BRDCFG1_DVIEN;
0333 out_8(lbc_lcs1_ba, b);
0334 break;
0335 case FSL_DIU_PORT_LVDS:
0336
0337
0338
0339
0340
0341 out_8(lbc_lcs0_ba, PX_BRDCFG1);
0342 b = in_8(lbc_lcs1_ba);
0343 b &= ~PX_BRDCFG1_DVIEN;
0344 b |= PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT;
0345 out_8(lbc_lcs1_ba, b);
0346 break;
0347 default:
0348 pr_err("p1022ds: unsupported monitor port %i\n", port);
0349 }
0350
0351 exit:
0352 if (lbc_lcs1_ba)
0353 iounmap(lbc_lcs1_ba);
0354 if (lbc_lcs0_ba)
0355 iounmap(lbc_lcs0_ba);
0356 if (lbc)
0357 iounmap(lbc);
0358 if (ecm)
0359 iounmap(ecm);
0360 if (guts)
0361 iounmap(guts);
0362
0363 of_node_put(law_node);
0364 of_node_put(lbc_node);
0365 of_node_put(guts_node);
0366 }
0367
0368
0369
0370
0371
0372
0373 void p1022ds_set_pixel_clock(unsigned int pixclock)
0374 {
0375 struct device_node *guts_np = NULL;
0376 struct ccsr_guts __iomem *guts;
0377 unsigned long freq;
0378 u64 temp;
0379 u32 pxclk;
0380
0381
0382 guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
0383 if (!guts_np) {
0384 pr_err("p1022ds: missing global utilities device node\n");
0385 return;
0386 }
0387
0388 guts = of_iomap(guts_np, 0);
0389 of_node_put(guts_np);
0390 if (!guts) {
0391 pr_err("p1022ds: could not map global utilities device\n");
0392 return;
0393 }
0394
0395
0396 temp = 1000000000000ULL;
0397 do_div(temp, pixclock);
0398 freq = temp;
0399
0400
0401
0402
0403
0404
0405 pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
0406 pxclk = clamp_t(u32, pxclk, 2, 255);
0407
0408
0409 clrbits32(&guts->clkdvdr,
0410 CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
0411
0412
0413 setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
0414
0415 iounmap(guts);
0416 }
0417
0418
0419
0420
0421 enum fsl_diu_monitor_port
0422 p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
0423 {
0424 switch (port) {
0425 case FSL_DIU_PORT_DVI:
0426 case FSL_DIU_PORT_LVDS:
0427 return port;
0428 default:
0429 return FSL_DIU_PORT_DVI;
0430 }
0431 }
0432
0433 #endif
0434
0435 void __init p1022_ds_pic_init(void)
0436 {
0437 struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
0438 MPIC_SINGLE_DEST_CPU,
0439 0, 256, " OpenPIC ");
0440 BUG_ON(mpic == NULL);
0441 mpic_init(mpic);
0442 }
0443
0444 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
0445
0446
0447 static bool fslfb;
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 static int __init early_video_setup(char *options)
0460 {
0461 fslfb = (strncmp(options, "fslfb:", 6) == 0);
0462
0463 return 0;
0464 }
0465 early_param("video", early_video_setup);
0466
0467 #endif
0468
0469
0470
0471
0472 static void __init p1022_ds_setup_arch(void)
0473 {
0474 if (ppc_md.progress)
0475 ppc_md.progress("p1022_ds_setup_arch()", 0);
0476
0477 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
0478 diu_ops.set_monitor_port = p1022ds_set_monitor_port;
0479 diu_ops.set_pixel_clock = p1022ds_set_pixel_clock;
0480 diu_ops.valid_monitor_port = p1022ds_valid_monitor_port;
0481
0482
0483
0484
0485
0486
0487
0488 if (fslfb) {
0489 struct device_node *np =
0490 of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc");
0491
0492 if (np) {
0493 struct device_node *np2;
0494
0495 of_node_get(np);
0496 np2 = of_find_compatible_node(np, NULL, "cfi-flash");
0497 if (np2) {
0498 static struct property nor_status = {
0499 .name = "status",
0500 .value = "disabled",
0501 .length = sizeof("disabled"),
0502 };
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512 pr_info("p1022ds: disabling %pOF node",
0513 np2);
0514 of_update_property(np2, &nor_status);
0515 of_node_put(np2);
0516 }
0517
0518 of_node_get(np);
0519 np2 = of_find_compatible_node(np, NULL,
0520 "fsl,elbc-fcm-nand");
0521 if (np2) {
0522 static struct property nand_status = {
0523 .name = "status",
0524 .value = "disabled",
0525 .length = sizeof("disabled"),
0526 };
0527
0528 pr_info("p1022ds: disabling %pOF node",
0529 np2);
0530 of_update_property(np2, &nand_status);
0531 of_node_put(np2);
0532 }
0533
0534 of_node_put(np);
0535 }
0536
0537 }
0538
0539 #endif
0540
0541 mpc85xx_smp_init();
0542
0543 fsl_pci_assign_primary();
0544
0545 swiotlb_detect_4g();
0546
0547 pr_info("Freescale P1022 DS reference board\n");
0548 }
0549
0550 machine_arch_initcall(p1022_ds, mpc85xx_common_publish_devices);
0551
0552
0553
0554
0555 static int __init p1022_ds_probe(void)
0556 {
0557 return of_machine_is_compatible("fsl,p1022ds");
0558 }
0559
0560 define_machine(p1022_ds) {
0561 .name = "P1022 DS",
0562 .probe = p1022_ds_probe,
0563 .setup_arch = p1022_ds_setup_arch,
0564 .init_IRQ = p1022_ds_pic_init,
0565 #ifdef CONFIG_PCI
0566 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
0567 .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
0568 #endif
0569 .get_irq = mpic_get_irq,
0570 .calibrate_decr = generic_calibrate_decr,
0571 .progress = udbg_progress,
0572 };