ddr_spd.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright 2008 Freescale Semiconductor, Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * Version 2 as published by the Free Software Foundation.
  7. */
  8. #include <common.h>
  9. #include <ddr_spd.h>
  10. /* used for ddr1 and ddr2 spd */
  11. static int
  12. spd_check(const u8 *buf, u8 spd_rev, u8 spd_cksum)
  13. {
  14. unsigned int cksum = 0;
  15. unsigned int i;
  16. /*
  17. * Check SPD revision supported
  18. * Rev 1.2 or less supported by this code
  19. */
  20. if (spd_rev >= 0x20) {
  21. printf("SPD revision %02X not supported by this code\n",
  22. spd_rev);
  23. return 1;
  24. }
  25. if (spd_rev > 0x13) {
  26. printf("SPD revision %02X not verified by this code\n",
  27. spd_rev);
  28. }
  29. /*
  30. * Calculate checksum
  31. */
  32. for (i = 0; i < 63; i++) {
  33. cksum += *buf++;
  34. }
  35. cksum &= 0xFF;
  36. if (cksum != spd_cksum) {
  37. printf("SPD checksum unexpected. "
  38. "Checksum in SPD = %02X, computed SPD = %02X\n",
  39. spd_cksum, cksum);
  40. return 1;
  41. }
  42. return 0;
  43. }
  44. unsigned int
  45. ddr1_spd_check(const ddr1_spd_eeprom_t *spd)
  46. {
  47. const u8 *p = (const u8 *)spd;
  48. return spd_check(p, spd->spd_rev, spd->cksum);
  49. }
  50. unsigned int
  51. ddr2_spd_check(const ddr2_spd_eeprom_t *spd)
  52. {
  53. const u8 *p = (const u8 *)spd;
  54. return spd_check(p, spd->spd_rev, spd->cksum);
  55. }
  56. /*
  57. * CRC16 compute for DDR3 SPD
  58. * Copied from DDR3 SPD spec.
  59. */
  60. static int
  61. crc16(char *ptr, int count)
  62. {
  63. int crc, i;
  64. crc = 0;
  65. while (--count >= 0) {
  66. crc = crc ^ (int)*ptr++ << 8;
  67. for (i = 0; i < 8; ++i)
  68. if (crc & 0x8000)
  69. crc = crc << 1 ^ 0x1021;
  70. else
  71. crc = crc << 1;
  72. }
  73. return crc & 0xffff;
  74. }
  75. unsigned int
  76. ddr3_spd_check(const ddr3_spd_eeprom_t *spd)
  77. {
  78. char *p = (char *)spd;
  79. int csum16;
  80. int len;
  81. char crc_lsb; /* byte 126 */
  82. char crc_msb; /* byte 127 */
  83. /*
  84. * SPD byte0[7] - CRC coverage
  85. * 0 = CRC covers bytes 0~125
  86. * 1 = CRC covers bytes 0~116
  87. */
  88. len = !(spd->info_size_crc & 0x80) ? 126 : 117;
  89. csum16 = crc16(p, len);
  90. crc_lsb = (char) (csum16 & 0xff);
  91. crc_msb = (char) (csum16 >> 8);
  92. if (spd->crc[0] == crc_lsb && spd->crc[1] == crc_msb) {
  93. return 0;
  94. } else {
  95. printf("SPD checksum unexpected.\n"
  96. "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
  97. "Checksum msb in SPD = %02X, computed SPD = %02X\n",
  98. spd->crc[0], crc_lsb, spd->crc[1], crc_msb);
  99. return 1;
  100. }
  101. }