0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008 #include <linux/kernel.h>
0009 #include <linux/types.h>
0010 #include <linux/slab.h>
0011 #include <linux/list.h>
0012 #include <linux/string.h>
0013 #include <linux/sched.h>
0014 #include <linux/smp.h>
0015 #include <linux/errno.h>
0016 #include <linux/init.h>
0017 #include <linux/of.h>
0018 #include <linux/of_device.h>
0019 #include <asm/spitfire.h>
0020 #include <asm/chmctrl.h>
0021 #include <asm/cpudata.h>
0022 #include <asm/oplib.h>
0023 #include <asm/prom.h>
0024 #include <asm/head.h>
0025 #include <asm/io.h>
0026 #include <asm/memctrl.h>
0027
0028 #define DRV_MODULE_NAME "chmc"
0029 #define PFX DRV_MODULE_NAME ": "
0030 #define DRV_MODULE_VERSION "0.2"
0031
0032 MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
0033 MODULE_DESCRIPTION("UltraSPARC-III memory controller driver");
0034 MODULE_LICENSE("GPL");
0035 MODULE_VERSION(DRV_MODULE_VERSION);
0036
0037 static int mc_type;
0038 #define MC_TYPE_SAFARI 1
0039 #define MC_TYPE_JBUS 2
0040
0041 static dimm_printer_t us3mc_dimm_printer;
0042
0043 #define CHMCTRL_NDGRPS 2
0044 #define CHMCTRL_NDIMMS 4
0045
0046 #define CHMC_DIMMS_PER_MC (CHMCTRL_NDGRPS * CHMCTRL_NDIMMS)
0047
0048
0049 struct chmc_obp_map {
0050 unsigned char dimm_map[144];
0051 unsigned char pin_map[576];
0052 };
0053
0054 #define DIMM_LABEL_SZ 8
0055
0056 struct chmc_obp_mem_layout {
0057
0058
0059
0060
0061 char dimm_labels[CHMC_DIMMS_PER_MC][DIMM_LABEL_SZ];
0062
0063
0064
0065
0066 char symmetric;
0067
0068 struct chmc_obp_map map[2];
0069 };
0070
0071 #define CHMCTRL_NBANKS 4
0072
0073 struct chmc_bank_info {
0074 struct chmc *p;
0075 int bank_id;
0076
0077 u64 raw_reg;
0078 int valid;
0079 int uk;
0080 int um;
0081 int lk;
0082 int lm;
0083 int interleave;
0084 unsigned long base;
0085 unsigned long size;
0086 };
0087
0088 struct chmc {
0089 struct list_head list;
0090 int portid;
0091
0092 struct chmc_obp_mem_layout layout_prop;
0093 int layout_size;
0094
0095 void __iomem *regs;
0096
0097 u64 timing_control1;
0098 u64 timing_control2;
0099 u64 timing_control3;
0100 u64 timing_control4;
0101 u64 memaddr_control;
0102
0103 struct chmc_bank_info logical_banks[CHMCTRL_NBANKS];
0104 };
0105
0106 #define JBUSMC_REGS_SIZE 8
0107
0108 #define JB_MC_REG1_DIMM2_BANK3 0x8000000000000000UL
0109 #define JB_MC_REG1_DIMM1_BANK1 0x4000000000000000UL
0110 #define JB_MC_REG1_DIMM2_BANK2 0x2000000000000000UL
0111 #define JB_MC_REG1_DIMM1_BANK0 0x1000000000000000UL
0112 #define JB_MC_REG1_XOR 0x0000010000000000UL
0113 #define JB_MC_REG1_ADDR_GEN_2 0x000000e000000000UL
0114 #define JB_MC_REG1_ADDR_GEN_2_SHIFT 37
0115 #define JB_MC_REG1_ADDR_GEN_1 0x0000001c00000000UL
0116 #define JB_MC_REG1_ADDR_GEN_1_SHIFT 34
0117 #define JB_MC_REG1_INTERLEAVE 0x0000000001800000UL
0118 #define JB_MC_REG1_INTERLEAVE_SHIFT 23
0119 #define JB_MC_REG1_DIMM2_PTYPE 0x0000000000200000UL
0120 #define JB_MC_REG1_DIMM2_PTYPE_SHIFT 21
0121 #define JB_MC_REG1_DIMM1_PTYPE 0x0000000000100000UL
0122 #define JB_MC_REG1_DIMM1_PTYPE_SHIFT 20
0123
0124 #define PART_TYPE_X8 0
0125 #define PART_TYPE_X4 1
0126
0127 #define INTERLEAVE_NONE 0
0128 #define INTERLEAVE_SAME 1
0129 #define INTERLEAVE_INTERNAL 2
0130 #define INTERLEAVE_BOTH 3
0131
0132 #define ADDR_GEN_128MB 0
0133 #define ADDR_GEN_256MB 1
0134 #define ADDR_GEN_512MB 2
0135 #define ADDR_GEN_1GB 3
0136
0137 #define JB_NUM_DIMM_GROUPS 2
0138 #define JB_NUM_DIMMS_PER_GROUP 2
0139 #define JB_NUM_DIMMS (JB_NUM_DIMM_GROUPS * JB_NUM_DIMMS_PER_GROUP)
0140
0141 struct jbusmc_obp_map {
0142 unsigned char dimm_map[18];
0143 unsigned char pin_map[144];
0144 };
0145
0146 struct jbusmc_obp_mem_layout {
0147
0148
0149
0150
0151 char dimm_labels[JB_NUM_DIMMS][DIMM_LABEL_SZ];
0152
0153
0154
0155
0156 char symmetric;
0157
0158 struct jbusmc_obp_map map;
0159
0160 char _pad;
0161 };
0162
0163 struct jbusmc_dimm_group {
0164 struct jbusmc *controller;
0165 int index;
0166 u64 base_addr;
0167 u64 size;
0168 };
0169
0170 struct jbusmc {
0171 void __iomem *regs;
0172 u64 mc_reg_1;
0173 u32 portid;
0174 struct jbusmc_obp_mem_layout layout;
0175 int layout_len;
0176 int num_dimm_groups;
0177 struct jbusmc_dimm_group dimm_groups[JB_NUM_DIMM_GROUPS];
0178 struct list_head list;
0179 };
0180
0181 static DEFINE_SPINLOCK(mctrl_list_lock);
0182 static LIST_HEAD(mctrl_list);
0183
0184 static void mc_list_add(struct list_head *list)
0185 {
0186 spin_lock(&mctrl_list_lock);
0187 list_add(list, &mctrl_list);
0188 spin_unlock(&mctrl_list_lock);
0189 }
0190
0191 static void mc_list_del(struct list_head *list)
0192 {
0193 spin_lock(&mctrl_list_lock);
0194 list_del_init(list);
0195 spin_unlock(&mctrl_list_lock);
0196 }
0197
0198 #define SYNDROME_MIN -1
0199 #define SYNDROME_MAX 144
0200
0201
0202
0203
0204 static int syndrome_to_qword_code(int syndrome_code)
0205 {
0206 if (syndrome_code < 128)
0207 syndrome_code += 16;
0208 else if (syndrome_code < 128 + 9)
0209 syndrome_code -= (128 - 7);
0210 else if (syndrome_code < (128 + 9 + 3))
0211 syndrome_code -= (128 + 9 - 4);
0212 else
0213 syndrome_code -= (128 + 9 + 3);
0214 return syndrome_code;
0215 }
0216
0217
0218
0219
0220
0221
0222 #define L2_LINE_SIZE 64
0223 #define L2_LINE_ADDR_MSK (L2_LINE_SIZE - 1)
0224 #define QW_PER_LINE 4
0225 #define QW_BYTES (L2_LINE_SIZE / QW_PER_LINE)
0226 #define QW_BITS 144
0227 #define SAFARI_LAST_BIT (576 - 1)
0228 #define JBUS_LAST_BIT (144 - 1)
0229
0230 static void get_pin_and_dimm_str(int syndrome_code, unsigned long paddr,
0231 int *pin_p, char **dimm_str_p, void *_prop,
0232 int base_dimm_offset)
0233 {
0234 int qword_code = syndrome_to_qword_code(syndrome_code);
0235 int cache_line_offset;
0236 int offset_inverse;
0237 int dimm_map_index;
0238 int map_val;
0239
0240 if (mc_type == MC_TYPE_JBUS) {
0241 struct jbusmc_obp_mem_layout *p = _prop;
0242
0243
0244 cache_line_offset = qword_code;
0245 offset_inverse = (JBUS_LAST_BIT - cache_line_offset);
0246 dimm_map_index = offset_inverse / 8;
0247 map_val = p->map.dimm_map[dimm_map_index];
0248 map_val = ((map_val >> ((7 - (offset_inverse & 7)))) & 1);
0249 *dimm_str_p = p->dimm_labels[base_dimm_offset + map_val];
0250 *pin_p = p->map.pin_map[cache_line_offset];
0251 } else {
0252 struct chmc_obp_mem_layout *p = _prop;
0253 struct chmc_obp_map *mp;
0254 int qword;
0255
0256
0257 if (p->symmetric)
0258 mp = &p->map[0];
0259 else
0260 mp = &p->map[1];
0261
0262 qword = (paddr & L2_LINE_ADDR_MSK) / QW_BYTES;
0263 cache_line_offset = ((3 - qword) * QW_BITS) + qword_code;
0264 offset_inverse = (SAFARI_LAST_BIT - cache_line_offset);
0265 dimm_map_index = offset_inverse >> 2;
0266 map_val = mp->dimm_map[dimm_map_index];
0267 map_val = ((map_val >> ((3 - (offset_inverse & 3)) << 1)) & 0x3);
0268 *dimm_str_p = p->dimm_labels[base_dimm_offset + map_val];
0269 *pin_p = mp->pin_map[cache_line_offset];
0270 }
0271 }
0272
0273 static struct jbusmc_dimm_group *jbusmc_find_dimm_group(unsigned long phys_addr)
0274 {
0275 struct jbusmc *p;
0276
0277 list_for_each_entry(p, &mctrl_list, list) {
0278 int i;
0279
0280 for (i = 0; i < p->num_dimm_groups; i++) {
0281 struct jbusmc_dimm_group *dp = &p->dimm_groups[i];
0282
0283 if (phys_addr < dp->base_addr ||
0284 (dp->base_addr + dp->size) <= phys_addr)
0285 continue;
0286
0287 return dp;
0288 }
0289 }
0290 return NULL;
0291 }
0292
0293 static int jbusmc_print_dimm(int syndrome_code,
0294 unsigned long phys_addr,
0295 char *buf, int buflen)
0296 {
0297 struct jbusmc_obp_mem_layout *prop;
0298 struct jbusmc_dimm_group *dp;
0299 struct jbusmc *p;
0300 int first_dimm;
0301
0302 dp = jbusmc_find_dimm_group(phys_addr);
0303 if (dp == NULL ||
0304 syndrome_code < SYNDROME_MIN ||
0305 syndrome_code > SYNDROME_MAX) {
0306 buf[0] = '?';
0307 buf[1] = '?';
0308 buf[2] = '?';
0309 buf[3] = '\0';
0310 return 0;
0311 }
0312 p = dp->controller;
0313 prop = &p->layout;
0314
0315 first_dimm = dp->index * JB_NUM_DIMMS_PER_GROUP;
0316
0317 if (syndrome_code != SYNDROME_MIN) {
0318 char *dimm_str;
0319 int pin;
0320
0321 get_pin_and_dimm_str(syndrome_code, phys_addr, &pin,
0322 &dimm_str, prop, first_dimm);
0323 sprintf(buf, "%s, pin %3d", dimm_str, pin);
0324 } else {
0325 int dimm;
0326
0327
0328
0329
0330 for (dimm = 0; dimm < JB_NUM_DIMMS_PER_GROUP; dimm++) {
0331 sprintf(buf, "%s ",
0332 prop->dimm_labels[first_dimm + dimm]);
0333 buf += strlen(buf);
0334 }
0335 }
0336
0337 return 0;
0338 }
0339
0340 static u64 jbusmc_dimm_group_size(u64 base,
0341 const struct linux_prom64_registers *mem_regs,
0342 int num_mem_regs)
0343 {
0344 u64 max = base + (8UL * 1024 * 1024 * 1024);
0345 u64 max_seen = base;
0346 int i;
0347
0348 for (i = 0; i < num_mem_regs; i++) {
0349 const struct linux_prom64_registers *ent;
0350 u64 this_base;
0351 u64 this_end;
0352
0353 ent = &mem_regs[i];
0354 this_base = ent->phys_addr;
0355 this_end = this_base + ent->reg_size;
0356 if (base < this_base || base >= this_end)
0357 continue;
0358 if (this_end > max)
0359 this_end = max;
0360 if (this_end > max_seen)
0361 max_seen = this_end;
0362 }
0363
0364 return max_seen - base;
0365 }
0366
0367 static void jbusmc_construct_one_dimm_group(struct jbusmc *p,
0368 unsigned long index,
0369 const struct linux_prom64_registers *mem_regs,
0370 int num_mem_regs)
0371 {
0372 struct jbusmc_dimm_group *dp = &p->dimm_groups[index];
0373
0374 dp->controller = p;
0375 dp->index = index;
0376
0377 dp->base_addr = (p->portid * (64UL * 1024 * 1024 * 1024));
0378 dp->base_addr += (index * (8UL * 1024 * 1024 * 1024));
0379 dp->size = jbusmc_dimm_group_size(dp->base_addr, mem_regs, num_mem_regs);
0380 }
0381
0382 static void jbusmc_construct_dimm_groups(struct jbusmc *p,
0383 const struct linux_prom64_registers *mem_regs,
0384 int num_mem_regs)
0385 {
0386 if (p->mc_reg_1 & JB_MC_REG1_DIMM1_BANK0) {
0387 jbusmc_construct_one_dimm_group(p, 0, mem_regs, num_mem_regs);
0388 p->num_dimm_groups++;
0389 }
0390 if (p->mc_reg_1 & JB_MC_REG1_DIMM2_BANK2) {
0391 jbusmc_construct_one_dimm_group(p, 1, mem_regs, num_mem_regs);
0392 p->num_dimm_groups++;
0393 }
0394 }
0395
0396 static int jbusmc_probe(struct platform_device *op)
0397 {
0398 const struct linux_prom64_registers *mem_regs;
0399 struct device_node *mem_node;
0400 int err, len, num_mem_regs;
0401 struct jbusmc *p;
0402 const u32 *prop;
0403 const void *ml;
0404
0405 err = -ENODEV;
0406 mem_node = of_find_node_by_path("/memory");
0407 if (!mem_node) {
0408 printk(KERN_ERR PFX "Cannot find /memory node.\n");
0409 goto out;
0410 }
0411 mem_regs = of_get_property(mem_node, "reg", &len);
0412 if (!mem_regs) {
0413 printk(KERN_ERR PFX "Cannot get reg property of /memory node.\n");
0414 goto out;
0415 }
0416 num_mem_regs = len / sizeof(*mem_regs);
0417
0418 err = -ENOMEM;
0419 p = kzalloc(sizeof(*p), GFP_KERNEL);
0420 if (!p) {
0421 printk(KERN_ERR PFX "Cannot allocate struct jbusmc.\n");
0422 goto out;
0423 }
0424
0425 INIT_LIST_HEAD(&p->list);
0426
0427 err = -ENODEV;
0428 prop = of_get_property(op->dev.of_node, "portid", &len);
0429 if (!prop || len != 4) {
0430 printk(KERN_ERR PFX "Cannot find portid.\n");
0431 goto out_free;
0432 }
0433
0434 p->portid = *prop;
0435
0436 prop = of_get_property(op->dev.of_node, "memory-control-register-1", &len);
0437 if (!prop || len != 8) {
0438 printk(KERN_ERR PFX "Cannot get memory control register 1.\n");
0439 goto out_free;
0440 }
0441
0442 p->mc_reg_1 = ((u64)prop[0] << 32) | (u64) prop[1];
0443
0444 err = -ENOMEM;
0445 p->regs = of_ioremap(&op->resource[0], 0, JBUSMC_REGS_SIZE, "jbusmc");
0446 if (!p->regs) {
0447 printk(KERN_ERR PFX "Cannot map jbusmc regs.\n");
0448 goto out_free;
0449 }
0450
0451 err = -ENODEV;
0452 ml = of_get_property(op->dev.of_node, "memory-layout", &p->layout_len);
0453 if (!ml) {
0454 printk(KERN_ERR PFX "Cannot get memory layout property.\n");
0455 goto out_iounmap;
0456 }
0457 if (p->layout_len > sizeof(p->layout)) {
0458 printk(KERN_ERR PFX "Unexpected memory-layout size %d\n",
0459 p->layout_len);
0460 goto out_iounmap;
0461 }
0462 memcpy(&p->layout, ml, p->layout_len);
0463
0464 jbusmc_construct_dimm_groups(p, mem_regs, num_mem_regs);
0465
0466 mc_list_add(&p->list);
0467
0468 printk(KERN_INFO PFX "UltraSPARC-IIIi memory controller at %pOF\n",
0469 op->dev.of_node);
0470
0471 dev_set_drvdata(&op->dev, p);
0472
0473 err = 0;
0474
0475 out:
0476 return err;
0477
0478 out_iounmap:
0479 of_iounmap(&op->resource[0], p->regs, JBUSMC_REGS_SIZE);
0480
0481 out_free:
0482 kfree(p);
0483 goto out;
0484 }
0485
0486
0487 static int chmc_bank_match(struct chmc_bank_info *bp, unsigned long phys_addr)
0488 {
0489 unsigned long upper_bits = (phys_addr & PA_UPPER_BITS) >> PA_UPPER_BITS_SHIFT;
0490 unsigned long lower_bits = (phys_addr & PA_LOWER_BITS) >> PA_LOWER_BITS_SHIFT;
0491
0492
0493 if (bp->valid == 0)
0494 return 0;
0495
0496
0497 upper_bits ^= bp->um;
0498 upper_bits = ~upper_bits;
0499 upper_bits |= bp->uk;
0500 upper_bits = ~upper_bits;
0501
0502 if (upper_bits)
0503 return 0;
0504
0505
0506 lower_bits ^= bp->lm;
0507 lower_bits = ~lower_bits;
0508 lower_bits |= bp->lk;
0509 lower_bits = ~lower_bits;
0510
0511 if (lower_bits)
0512 return 0;
0513
0514
0515 return 1;
0516 }
0517
0518
0519 static struct chmc_bank_info *chmc_find_bank(unsigned long phys_addr)
0520 {
0521 struct chmc *p;
0522
0523 list_for_each_entry(p, &mctrl_list, list) {
0524 int bank_no;
0525
0526 for (bank_no = 0; bank_no < CHMCTRL_NBANKS; bank_no++) {
0527 struct chmc_bank_info *bp;
0528
0529 bp = &p->logical_banks[bank_no];
0530 if (chmc_bank_match(bp, phys_addr))
0531 return bp;
0532 }
0533 }
0534
0535 return NULL;
0536 }
0537
0538
0539 static int chmc_print_dimm(int syndrome_code,
0540 unsigned long phys_addr,
0541 char *buf, int buflen)
0542 {
0543 struct chmc_bank_info *bp;
0544 struct chmc_obp_mem_layout *prop;
0545 int bank_in_controller, first_dimm;
0546
0547 bp = chmc_find_bank(phys_addr);
0548 if (bp == NULL ||
0549 syndrome_code < SYNDROME_MIN ||
0550 syndrome_code > SYNDROME_MAX) {
0551 buf[0] = '?';
0552 buf[1] = '?';
0553 buf[2] = '?';
0554 buf[3] = '\0';
0555 return 0;
0556 }
0557
0558 prop = &bp->p->layout_prop;
0559 bank_in_controller = bp->bank_id & (CHMCTRL_NBANKS - 1);
0560 first_dimm = (bank_in_controller & (CHMCTRL_NDGRPS - 1));
0561 first_dimm *= CHMCTRL_NDIMMS;
0562
0563 if (syndrome_code != SYNDROME_MIN) {
0564 char *dimm_str;
0565 int pin;
0566
0567 get_pin_and_dimm_str(syndrome_code, phys_addr, &pin,
0568 &dimm_str, prop, first_dimm);
0569 sprintf(buf, "%s, pin %3d", dimm_str, pin);
0570 } else {
0571 int dimm;
0572
0573
0574
0575
0576 for (dimm = 0; dimm < CHMCTRL_NDIMMS; dimm++) {
0577 sprintf(buf, "%s ",
0578 prop->dimm_labels[first_dimm + dimm]);
0579 buf += strlen(buf);
0580 }
0581 }
0582 return 0;
0583 }
0584
0585
0586
0587
0588
0589
0590 static u64 chmc_read_mcreg(struct chmc *p, unsigned long offset)
0591 {
0592 unsigned long ret, this_cpu;
0593
0594 preempt_disable();
0595
0596 this_cpu = real_hard_smp_processor_id();
0597
0598 if (p->portid == this_cpu) {
0599 __asm__ __volatile__("ldxa [%1] %2, %0"
0600 : "=r" (ret)
0601 : "r" (offset), "i" (ASI_MCU_CTRL_REG));
0602 } else {
0603 __asm__ __volatile__("ldxa [%1] %2, %0"
0604 : "=r" (ret)
0605 : "r" (p->regs + offset),
0606 "i" (ASI_PHYS_BYPASS_EC_E));
0607 }
0608
0609 preempt_enable();
0610
0611 return ret;
0612 }
0613
0614 #if 0
0615 static void chmc_write_mcreg(struct chmc *p, unsigned long offset, u64 val)
0616 {
0617 if (p->portid == smp_processor_id()) {
0618 __asm__ __volatile__("stxa %0, [%1] %2"
0619 : : "r" (val),
0620 "r" (offset), "i" (ASI_MCU_CTRL_REG));
0621 } else {
0622 __asm__ __volatile__("ldxa %0, [%1] %2"
0623 : : "r" (val),
0624 "r" (p->regs + offset),
0625 "i" (ASI_PHYS_BYPASS_EC_E));
0626 }
0627 }
0628 #endif
0629
0630 static void chmc_interpret_one_decode_reg(struct chmc *p, int which_bank, u64 val)
0631 {
0632 struct chmc_bank_info *bp = &p->logical_banks[which_bank];
0633
0634 bp->p = p;
0635 bp->bank_id = (CHMCTRL_NBANKS * p->portid) + which_bank;
0636 bp->raw_reg = val;
0637 bp->valid = (val & MEM_DECODE_VALID) >> MEM_DECODE_VALID_SHIFT;
0638 bp->uk = (val & MEM_DECODE_UK) >> MEM_DECODE_UK_SHIFT;
0639 bp->um = (val & MEM_DECODE_UM) >> MEM_DECODE_UM_SHIFT;
0640 bp->lk = (val & MEM_DECODE_LK) >> MEM_DECODE_LK_SHIFT;
0641 bp->lm = (val & MEM_DECODE_LM) >> MEM_DECODE_LM_SHIFT;
0642
0643 bp->base = (bp->um);
0644 bp->base &= ~(bp->uk);
0645 bp->base <<= PA_UPPER_BITS_SHIFT;
0646
0647 switch(bp->lk) {
0648 case 0xf:
0649 default:
0650 bp->interleave = 1;
0651 break;
0652
0653 case 0xe:
0654 bp->interleave = 2;
0655 break;
0656
0657 case 0xc:
0658 bp->interleave = 4;
0659 break;
0660
0661 case 0x8:
0662 bp->interleave = 8;
0663 break;
0664
0665 case 0x0:
0666 bp->interleave = 16;
0667 break;
0668 }
0669
0670
0671
0672
0673 bp->size = (((unsigned long)bp->uk &
0674 ((1UL << 10UL) - 1UL)) + 1UL) << PA_UPPER_BITS_SHIFT;
0675 bp->size /= bp->interleave;
0676 }
0677
0678 static void chmc_fetch_decode_regs(struct chmc *p)
0679 {
0680 if (p->layout_size == 0)
0681 return;
0682
0683 chmc_interpret_one_decode_reg(p, 0,
0684 chmc_read_mcreg(p, CHMCTRL_DECODE1));
0685 chmc_interpret_one_decode_reg(p, 1,
0686 chmc_read_mcreg(p, CHMCTRL_DECODE2));
0687 chmc_interpret_one_decode_reg(p, 2,
0688 chmc_read_mcreg(p, CHMCTRL_DECODE3));
0689 chmc_interpret_one_decode_reg(p, 3,
0690 chmc_read_mcreg(p, CHMCTRL_DECODE4));
0691 }
0692
0693 static int chmc_probe(struct platform_device *op)
0694 {
0695 struct device_node *dp = op->dev.of_node;
0696 unsigned long ver;
0697 const void *pval;
0698 int len, portid;
0699 struct chmc *p;
0700 int err;
0701
0702 err = -ENODEV;
0703 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
0704 if ((ver >> 32UL) == __JALAPENO_ID ||
0705 (ver >> 32UL) == __SERRANO_ID)
0706 goto out;
0707
0708 portid = of_getintprop_default(dp, "portid", -1);
0709 if (portid == -1)
0710 goto out;
0711
0712 pval = of_get_property(dp, "memory-layout", &len);
0713 if (pval && len > sizeof(p->layout_prop)) {
0714 printk(KERN_ERR PFX "Unexpected memory-layout property "
0715 "size %d.\n", len);
0716 goto out;
0717 }
0718
0719 err = -ENOMEM;
0720 p = kzalloc(sizeof(*p), GFP_KERNEL);
0721 if (!p) {
0722 printk(KERN_ERR PFX "Could not allocate struct chmc.\n");
0723 goto out;
0724 }
0725
0726 p->portid = portid;
0727 p->layout_size = len;
0728 if (!pval)
0729 p->layout_size = 0;
0730 else
0731 memcpy(&p->layout_prop, pval, len);
0732
0733 p->regs = of_ioremap(&op->resource[0], 0, 0x48, "chmc");
0734 if (!p->regs) {
0735 printk(KERN_ERR PFX "Could not map registers.\n");
0736 goto out_free;
0737 }
0738
0739 if (p->layout_size != 0UL) {
0740 p->timing_control1 = chmc_read_mcreg(p, CHMCTRL_TCTRL1);
0741 p->timing_control2 = chmc_read_mcreg(p, CHMCTRL_TCTRL2);
0742 p->timing_control3 = chmc_read_mcreg(p, CHMCTRL_TCTRL3);
0743 p->timing_control4 = chmc_read_mcreg(p, CHMCTRL_TCTRL4);
0744 p->memaddr_control = chmc_read_mcreg(p, CHMCTRL_MACTRL);
0745 }
0746
0747 chmc_fetch_decode_regs(p);
0748
0749 mc_list_add(&p->list);
0750
0751 printk(KERN_INFO PFX "UltraSPARC-III memory controller at %pOF [%s]\n",
0752 dp,
0753 (p->layout_size ? "ACTIVE" : "INACTIVE"));
0754
0755 dev_set_drvdata(&op->dev, p);
0756
0757 err = 0;
0758
0759 out:
0760 return err;
0761
0762 out_free:
0763 kfree(p);
0764 goto out;
0765 }
0766
0767 static int us3mc_probe(struct platform_device *op)
0768 {
0769 if (mc_type == MC_TYPE_SAFARI)
0770 return chmc_probe(op);
0771 else if (mc_type == MC_TYPE_JBUS)
0772 return jbusmc_probe(op);
0773 return -ENODEV;
0774 }
0775
0776 static void chmc_destroy(struct platform_device *op, struct chmc *p)
0777 {
0778 list_del(&p->list);
0779 of_iounmap(&op->resource[0], p->regs, 0x48);
0780 kfree(p);
0781 }
0782
0783 static void jbusmc_destroy(struct platform_device *op, struct jbusmc *p)
0784 {
0785 mc_list_del(&p->list);
0786 of_iounmap(&op->resource[0], p->regs, JBUSMC_REGS_SIZE);
0787 kfree(p);
0788 }
0789
0790 static int us3mc_remove(struct platform_device *op)
0791 {
0792 void *p = dev_get_drvdata(&op->dev);
0793
0794 if (p) {
0795 if (mc_type == MC_TYPE_SAFARI)
0796 chmc_destroy(op, p);
0797 else if (mc_type == MC_TYPE_JBUS)
0798 jbusmc_destroy(op, p);
0799 }
0800 return 0;
0801 }
0802
0803 static const struct of_device_id us3mc_match[] = {
0804 {
0805 .name = "memory-controller",
0806 },
0807 {},
0808 };
0809 MODULE_DEVICE_TABLE(of, us3mc_match);
0810
0811 static struct platform_driver us3mc_driver = {
0812 .driver = {
0813 .name = "us3mc",
0814 .of_match_table = us3mc_match,
0815 },
0816 .probe = us3mc_probe,
0817 .remove = us3mc_remove,
0818 };
0819
0820 static inline bool us3mc_platform(void)
0821 {
0822 if (tlb_type == cheetah || tlb_type == cheetah_plus)
0823 return true;
0824 return false;
0825 }
0826
0827 static int __init us3mc_init(void)
0828 {
0829 unsigned long ver;
0830 int ret;
0831
0832 if (!us3mc_platform())
0833 return -ENODEV;
0834
0835 __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver));
0836 if ((ver >> 32UL) == __JALAPENO_ID ||
0837 (ver >> 32UL) == __SERRANO_ID) {
0838 mc_type = MC_TYPE_JBUS;
0839 us3mc_dimm_printer = jbusmc_print_dimm;
0840 } else {
0841 mc_type = MC_TYPE_SAFARI;
0842 us3mc_dimm_printer = chmc_print_dimm;
0843 }
0844
0845 ret = register_dimm_printer(us3mc_dimm_printer);
0846
0847 if (!ret) {
0848 ret = platform_driver_register(&us3mc_driver);
0849 if (ret)
0850 unregister_dimm_printer(us3mc_dimm_printer);
0851 }
0852 return ret;
0853 }
0854
0855 static void __exit us3mc_cleanup(void)
0856 {
0857 if (us3mc_platform()) {
0858 unregister_dimm_printer(us3mc_dimm_printer);
0859 platform_driver_unregister(&us3mc_driver);
0860 }
0861 }
0862
0863 module_init(us3mc_init);
0864 module_exit(us3mc_cleanup);