diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-08-29 15:59:42 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-29 15:59:42 -0400 |
commit | 70d374ea9907036e15574a5ce89219edd5baee10 (patch) | |
tree | b858bb4a841eb91b1d91b41c33698d05fa7bfb37 /drivers/scsi/sata_sx4.c | |
parent | aa7e16d6b88b3b38db0d2ee49ed5e44e7b2045ec (diff) | |
parent | bf4e70e54cf31dcca48d279c7f7e71328eebe749 (diff) |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/scsi/sata_sx4.c')
-rw-r--r-- | drivers/scsi/sata_sx4.c | 146 |
1 files changed, 76 insertions, 70 deletions
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index c7f6ec262a15..c72fcc46f0fa 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -99,7 +99,7 @@ enum { | |||
99 | PDC_DIMM1_CONTROL_OFFSET = 0x84, | 99 | PDC_DIMM1_CONTROL_OFFSET = 0x84, |
100 | PDC_SDRAM_CONTROL_OFFSET = 0x88, | 100 | PDC_SDRAM_CONTROL_OFFSET = 0x88, |
101 | PDC_I2C_WRITE = 0x00000000, | 101 | PDC_I2C_WRITE = 0x00000000, |
102 | PDC_I2C_READ = 0x00000040, | 102 | PDC_I2C_READ = 0x00000040, |
103 | PDC_I2C_START = 0x00000080, | 103 | PDC_I2C_START = 0x00000080, |
104 | PDC_I2C_MASK_INT = 0x00000020, | 104 | PDC_I2C_MASK_INT = 0x00000020, |
105 | PDC_I2C_COMPLETE = 0x00010000, | 105 | PDC_I2C_COMPLETE = 0x00010000, |
@@ -110,16 +110,16 @@ enum { | |||
110 | PDC_DIMM_SPD_COLUMN_NUM = 4, | 110 | PDC_DIMM_SPD_COLUMN_NUM = 4, |
111 | PDC_DIMM_SPD_MODULE_ROW = 5, | 111 | PDC_DIMM_SPD_MODULE_ROW = 5, |
112 | PDC_DIMM_SPD_TYPE = 11, | 112 | PDC_DIMM_SPD_TYPE = 11, |
113 | PDC_DIMM_SPD_FRESH_RATE = 12, | 113 | PDC_DIMM_SPD_FRESH_RATE = 12, |
114 | PDC_DIMM_SPD_BANK_NUM = 17, | 114 | PDC_DIMM_SPD_BANK_NUM = 17, |
115 | PDC_DIMM_SPD_CAS_LATENCY = 18, | 115 | PDC_DIMM_SPD_CAS_LATENCY = 18, |
116 | PDC_DIMM_SPD_ATTRIBUTE = 21, | 116 | PDC_DIMM_SPD_ATTRIBUTE = 21, |
117 | PDC_DIMM_SPD_ROW_PRE_CHARGE = 27, | 117 | PDC_DIMM_SPD_ROW_PRE_CHARGE = 27, |
118 | PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28, | 118 | PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28, |
119 | PDC_DIMM_SPD_RAS_CAS_DELAY = 29, | 119 | PDC_DIMM_SPD_RAS_CAS_DELAY = 29, |
120 | PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30, | 120 | PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30, |
121 | PDC_DIMM_SPD_SYSTEM_FREQ = 126, | 121 | PDC_DIMM_SPD_SYSTEM_FREQ = 126, |
122 | PDC_CTL_STATUS = 0x08, | 122 | PDC_CTL_STATUS = 0x08, |
123 | PDC_DIMM_WINDOW_CTLR = 0x0C, | 123 | PDC_DIMM_WINDOW_CTLR = 0x0C, |
124 | PDC_TIME_CONTROL = 0x3C, | 124 | PDC_TIME_CONTROL = 0x3C, |
125 | PDC_TIME_PERIOD = 0x40, | 125 | PDC_TIME_PERIOD = 0x40, |
@@ -162,15 +162,15 @@ static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf); | |||
162 | static void pdc20621_host_stop(struct ata_host_set *host_set); | 162 | static void pdc20621_host_stop(struct ata_host_set *host_set); |
163 | static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe); | 163 | static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe); |
164 | static int pdc20621_detect_dimm(struct ata_probe_ent *pe); | 164 | static int pdc20621_detect_dimm(struct ata_probe_ent *pe); |
165 | static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, | 165 | static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, |
166 | u32 device, u32 subaddr, u32 *pdata); | 166 | u32 device, u32 subaddr, u32 *pdata); |
167 | static int pdc20621_prog_dimm0(struct ata_probe_ent *pe); | 167 | static int pdc20621_prog_dimm0(struct ata_probe_ent *pe); |
168 | static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe); | 168 | static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe); |
169 | #ifdef ATA_VERBOSE_DEBUG | 169 | #ifdef ATA_VERBOSE_DEBUG |
170 | static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, | 170 | static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, |
171 | void *psource, u32 offset, u32 size); | 171 | void *psource, u32 offset, u32 size); |
172 | #endif | 172 | #endif |
173 | static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, | 173 | static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, |
174 | void *psource, u32 offset, u32 size); | 174 | void *psource, u32 offset, u32 size); |
175 | static void pdc20621_irq_clear(struct ata_port *ap); | 175 | static void pdc20621_irq_clear(struct ata_port *ap); |
176 | static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); | 176 | static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); |
@@ -830,7 +830,8 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re | |||
830 | ap = host_set->ports[port_no]; | 830 | ap = host_set->ports[port_no]; |
831 | tmp = mask & (1 << i); | 831 | tmp = mask & (1 << i); |
832 | VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); | 832 | VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); |
833 | if (tmp && ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 833 | if (tmp && ap && |
834 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
834 | struct ata_queued_cmd *qc; | 835 | struct ata_queued_cmd *qc; |
835 | 836 | ||
836 | qc = ata_qc_from_tag(ap, ap->active_tag); | 837 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -852,10 +853,14 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re | |||
852 | static void pdc_eng_timeout(struct ata_port *ap) | 853 | static void pdc_eng_timeout(struct ata_port *ap) |
853 | { | 854 | { |
854 | u8 drv_stat; | 855 | u8 drv_stat; |
856 | struct ata_host_set *host_set = ap->host_set; | ||
855 | struct ata_queued_cmd *qc; | 857 | struct ata_queued_cmd *qc; |
858 | unsigned long flags; | ||
856 | 859 | ||
857 | DPRINTK("ENTER\n"); | 860 | DPRINTK("ENTER\n"); |
858 | 861 | ||
862 | spin_lock_irqsave(&host_set->lock, flags); | ||
863 | |||
859 | qc = ata_qc_from_tag(ap, ap->active_tag); | 864 | qc = ata_qc_from_tag(ap, ap->active_tag); |
860 | if (!qc) { | 865 | if (!qc) { |
861 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | 866 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", |
@@ -889,6 +894,7 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
889 | } | 894 | } |
890 | 895 | ||
891 | out: | 896 | out: |
897 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
892 | DPRINTK("EXIT\n"); | 898 | DPRINTK("EXIT\n"); |
893 | } | 899 | } |
894 | 900 | ||
@@ -927,7 +933,7 @@ static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base) | |||
927 | 933 | ||
928 | 934 | ||
929 | #ifdef ATA_VERBOSE_DEBUG | 935 | #ifdef ATA_VERBOSE_DEBUG |
930 | static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, | 936 | static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, |
931 | u32 offset, u32 size) | 937 | u32 offset, u32 size) |
932 | { | 938 | { |
933 | u32 window_size; | 939 | u32 window_size; |
@@ -941,9 +947,9 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, | |||
941 | /* hard-code chip #0 */ | 947 | /* hard-code chip #0 */ |
942 | mmio += PDC_CHIP0_OFS; | 948 | mmio += PDC_CHIP0_OFS; |
943 | 949 | ||
944 | page_mask = 0x00; | 950 | page_mask = 0x00; |
945 | window_size = 0x2000 * 4; /* 32K byte uchar size */ | 951 | window_size = 0x2000 * 4; /* 32K byte uchar size */ |
946 | idx = (u16) (offset / window_size); | 952 | idx = (u16) (offset / window_size); |
947 | 953 | ||
948 | writel(0x01, mmio + PDC_GENERAL_CTLR); | 954 | writel(0x01, mmio + PDC_GENERAL_CTLR); |
949 | readl(mmio + PDC_GENERAL_CTLR); | 955 | readl(mmio + PDC_GENERAL_CTLR); |
@@ -952,19 +958,19 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, | |||
952 | 958 | ||
953 | offset -= (idx * window_size); | 959 | offset -= (idx * window_size); |
954 | idx++; | 960 | idx++; |
955 | dist = ((long) (window_size - (offset + size))) >= 0 ? size : | 961 | dist = ((long) (window_size - (offset + size))) >= 0 ? size : |
956 | (long) (window_size - offset); | 962 | (long) (window_size - offset); |
957 | memcpy_fromio((char *) psource, (char *) (dimm_mmio + offset / 4), | 963 | memcpy_fromio((char *) psource, (char *) (dimm_mmio + offset / 4), |
958 | dist); | 964 | dist); |
959 | 965 | ||
960 | psource += dist; | 966 | psource += dist; |
961 | size -= dist; | 967 | size -= dist; |
962 | for (; (long) size >= (long) window_size ;) { | 968 | for (; (long) size >= (long) window_size ;) { |
963 | writel(0x01, mmio + PDC_GENERAL_CTLR); | 969 | writel(0x01, mmio + PDC_GENERAL_CTLR); |
964 | readl(mmio + PDC_GENERAL_CTLR); | 970 | readl(mmio + PDC_GENERAL_CTLR); |
965 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 971 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
966 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 972 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
967 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), | 973 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), |
968 | window_size / 4); | 974 | window_size / 4); |
969 | psource += window_size; | 975 | psource += window_size; |
970 | size -= window_size; | 976 | size -= window_size; |
@@ -976,14 +982,14 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, | |||
976 | readl(mmio + PDC_GENERAL_CTLR); | 982 | readl(mmio + PDC_GENERAL_CTLR); |
977 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 983 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
978 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 984 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
979 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), | 985 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), |
980 | size / 4); | 986 | size / 4); |
981 | } | 987 | } |
982 | } | 988 | } |
983 | #endif | 989 | #endif |
984 | 990 | ||
985 | 991 | ||
986 | static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | 992 | static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, |
987 | u32 offset, u32 size) | 993 | u32 offset, u32 size) |
988 | { | 994 | { |
989 | u32 window_size; | 995 | u32 window_size; |
@@ -994,16 +1000,16 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | |||
994 | struct pdc_host_priv *hpriv = pe->private_data; | 1000 | struct pdc_host_priv *hpriv = pe->private_data; |
995 | void *dimm_mmio = hpriv->dimm_mmio; | 1001 | void *dimm_mmio = hpriv->dimm_mmio; |
996 | 1002 | ||
997 | /* hard-code chip #0 */ | 1003 | /* hard-code chip #0 */ |
998 | mmio += PDC_CHIP0_OFS; | 1004 | mmio += PDC_CHIP0_OFS; |
999 | 1005 | ||
1000 | page_mask = 0x00; | 1006 | page_mask = 0x00; |
1001 | window_size = 0x2000 * 4; /* 32K byte uchar size */ | 1007 | window_size = 0x2000 * 4; /* 32K byte uchar size */ |
1002 | idx = (u16) (offset / window_size); | 1008 | idx = (u16) (offset / window_size); |
1003 | 1009 | ||
1004 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 1010 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
1005 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 1011 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
1006 | offset -= (idx * window_size); | 1012 | offset -= (idx * window_size); |
1007 | idx++; | 1013 | idx++; |
1008 | dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size : | 1014 | dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size : |
1009 | (long) (window_size - offset); | 1015 | (long) (window_size - offset); |
@@ -1011,12 +1017,12 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | |||
1011 | writel(0x01, mmio + PDC_GENERAL_CTLR); | 1017 | writel(0x01, mmio + PDC_GENERAL_CTLR); |
1012 | readl(mmio + PDC_GENERAL_CTLR); | 1018 | readl(mmio + PDC_GENERAL_CTLR); |
1013 | 1019 | ||
1014 | psource += dist; | 1020 | psource += dist; |
1015 | size -= dist; | 1021 | size -= dist; |
1016 | for (; (long) size >= (long) window_size ;) { | 1022 | for (; (long) size >= (long) window_size ;) { |
1017 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 1023 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
1018 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 1024 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
1019 | memcpy_toio((char *) (dimm_mmio), (char *) psource, | 1025 | memcpy_toio((char *) (dimm_mmio), (char *) psource, |
1020 | window_size / 4); | 1026 | window_size / 4); |
1021 | writel(0x01, mmio + PDC_GENERAL_CTLR); | 1027 | writel(0x01, mmio + PDC_GENERAL_CTLR); |
1022 | readl(mmio + PDC_GENERAL_CTLR); | 1028 | readl(mmio + PDC_GENERAL_CTLR); |
@@ -1024,7 +1030,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | |||
1024 | size -= window_size; | 1030 | size -= window_size; |
1025 | idx ++; | 1031 | idx ++; |
1026 | } | 1032 | } |
1027 | 1033 | ||
1028 | if (size) { | 1034 | if (size) { |
1029 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 1035 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
1030 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 1036 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
@@ -1035,12 +1041,12 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | |||
1035 | } | 1041 | } |
1036 | 1042 | ||
1037 | 1043 | ||
1038 | static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, | 1044 | static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, |
1039 | u32 subaddr, u32 *pdata) | 1045 | u32 subaddr, u32 *pdata) |
1040 | { | 1046 | { |
1041 | void *mmio = pe->mmio_base; | 1047 | void *mmio = pe->mmio_base; |
1042 | u32 i2creg = 0; | 1048 | u32 i2creg = 0; |
1043 | u32 status; | 1049 | u32 status; |
1044 | u32 count =0; | 1050 | u32 count =0; |
1045 | 1051 | ||
1046 | /* hard-code chip #0 */ | 1052 | /* hard-code chip #0 */ |
@@ -1054,7 +1060,7 @@ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, | |||
1054 | readl(mmio + PDC_I2C_ADDR_DATA_OFFSET); | 1060 | readl(mmio + PDC_I2C_ADDR_DATA_OFFSET); |
1055 | 1061 | ||
1056 | /* Write Control to perform read operation, mask int */ | 1062 | /* Write Control to perform read operation, mask int */ |
1057 | writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT, | 1063 | writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT, |
1058 | mmio + PDC_I2C_CONTROL_OFFSET); | 1064 | mmio + PDC_I2C_CONTROL_OFFSET); |
1059 | 1065 | ||
1060 | for (count = 0; count <= 1000; count ++) { | 1066 | for (count = 0; count <= 1000; count ++) { |
@@ -1067,26 +1073,26 @@ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, | |||
1067 | } | 1073 | } |
1068 | 1074 | ||
1069 | *pdata = (status >> 8) & 0x000000ff; | 1075 | *pdata = (status >> 8) & 0x000000ff; |
1070 | return 1; | 1076 | return 1; |
1071 | } | 1077 | } |
1072 | 1078 | ||
1073 | 1079 | ||
1074 | static int pdc20621_detect_dimm(struct ata_probe_ent *pe) | 1080 | static int pdc20621_detect_dimm(struct ata_probe_ent *pe) |
1075 | { | 1081 | { |
1076 | u32 data=0 ; | 1082 | u32 data=0 ; |
1077 | if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, | 1083 | if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, |
1078 | PDC_DIMM_SPD_SYSTEM_FREQ, &data)) { | 1084 | PDC_DIMM_SPD_SYSTEM_FREQ, &data)) { |
1079 | if (data == 100) | 1085 | if (data == 100) |
1080 | return 100; | 1086 | return 100; |
1081 | } else | 1087 | } else |
1082 | return 0; | 1088 | return 0; |
1083 | 1089 | ||
1084 | if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) { | 1090 | if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) { |
1085 | if(data <= 0x75) | 1091 | if(data <= 0x75) |
1086 | return 133; | 1092 | return 133; |
1087 | } else | 1093 | } else |
1088 | return 0; | 1094 | return 0; |
1089 | 1095 | ||
1090 | return 0; | 1096 | return 0; |
1091 | } | 1097 | } |
1092 | 1098 | ||
@@ -1096,15 +1102,15 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1096 | u32 spd0[50]; | 1102 | u32 spd0[50]; |
1097 | u32 data = 0; | 1103 | u32 data = 0; |
1098 | int size, i; | 1104 | int size, i; |
1099 | u8 bdimmsize; | 1105 | u8 bdimmsize; |
1100 | void *mmio = pe->mmio_base; | 1106 | void *mmio = pe->mmio_base; |
1101 | static const struct { | 1107 | static const struct { |
1102 | unsigned int reg; | 1108 | unsigned int reg; |
1103 | unsigned int ofs; | 1109 | unsigned int ofs; |
1104 | } pdc_i2c_read_data [] = { | 1110 | } pdc_i2c_read_data [] = { |
1105 | { PDC_DIMM_SPD_TYPE, 11 }, | 1111 | { PDC_DIMM_SPD_TYPE, 11 }, |
1106 | { PDC_DIMM_SPD_FRESH_RATE, 12 }, | 1112 | { PDC_DIMM_SPD_FRESH_RATE, 12 }, |
1107 | { PDC_DIMM_SPD_COLUMN_NUM, 4 }, | 1113 | { PDC_DIMM_SPD_COLUMN_NUM, 4 }, |
1108 | { PDC_DIMM_SPD_ATTRIBUTE, 21 }, | 1114 | { PDC_DIMM_SPD_ATTRIBUTE, 21 }, |
1109 | { PDC_DIMM_SPD_ROW_NUM, 3 }, | 1115 | { PDC_DIMM_SPD_ROW_NUM, 3 }, |
1110 | { PDC_DIMM_SPD_BANK_NUM, 17 }, | 1116 | { PDC_DIMM_SPD_BANK_NUM, 17 }, |
@@ -1113,7 +1119,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1113 | { PDC_DIMM_SPD_ROW_ACTIVE_DELAY, 28 }, | 1119 | { PDC_DIMM_SPD_ROW_ACTIVE_DELAY, 28 }, |
1114 | { PDC_DIMM_SPD_RAS_CAS_DELAY, 29 }, | 1120 | { PDC_DIMM_SPD_RAS_CAS_DELAY, 29 }, |
1115 | { PDC_DIMM_SPD_ACTIVE_PRECHARGE, 30 }, | 1121 | { PDC_DIMM_SPD_ACTIVE_PRECHARGE, 30 }, |
1116 | { PDC_DIMM_SPD_CAS_LATENCY, 18 }, | 1122 | { PDC_DIMM_SPD_CAS_LATENCY, 18 }, |
1117 | }; | 1123 | }; |
1118 | 1124 | ||
1119 | /* hard-code chip #0 */ | 1125 | /* hard-code chip #0 */ |
@@ -1121,17 +1127,17 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1121 | 1127 | ||
1122 | for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++) | 1128 | for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++) |
1123 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, | 1129 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, |
1124 | pdc_i2c_read_data[i].reg, | 1130 | pdc_i2c_read_data[i].reg, |
1125 | &spd0[pdc_i2c_read_data[i].ofs]); | 1131 | &spd0[pdc_i2c_read_data[i].ofs]); |
1126 | 1132 | ||
1127 | data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4); | 1133 | data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4); |
1128 | data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) | | 1134 | data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) | |
1129 | ((((spd0[27] + 9) / 10) - 1) << 8) ; | 1135 | ((((spd0[27] + 9) / 10) - 1) << 8) ; |
1130 | data |= (((((spd0[29] > spd0[28]) | 1136 | data |= (((((spd0[29] > spd0[28]) |
1131 | ? spd0[29] : spd0[28]) + 9) / 10) - 1) << 10; | 1137 | ? spd0[29] : spd0[28]) + 9) / 10) - 1) << 10; |
1132 | data |= ((spd0[30] - spd0[29] + 9) / 10 - 2) << 12; | 1138 | data |= ((spd0[30] - spd0[29] + 9) / 10 - 2) << 12; |
1133 | 1139 | ||
1134 | if (spd0[18] & 0x08) | 1140 | if (spd0[18] & 0x08) |
1135 | data |= ((0x03) << 14); | 1141 | data |= ((0x03) << 14); |
1136 | else if (spd0[18] & 0x04) | 1142 | else if (spd0[18] & 0x04) |
1137 | data |= ((0x02) << 14); | 1143 | data |= ((0x02) << 14); |
@@ -1140,7 +1146,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1140 | else | 1146 | else |
1141 | data |= (0 << 14); | 1147 | data |= (0 << 14); |
1142 | 1148 | ||
1143 | /* | 1149 | /* |
1144 | Calculate the size of bDIMMSize (power of 2) and | 1150 | Calculate the size of bDIMMSize (power of 2) and |
1145 | merge the DIMM size by program start/end address. | 1151 | merge the DIMM size by program start/end address. |
1146 | */ | 1152 | */ |
@@ -1150,9 +1156,9 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1150 | data |= (((size / 16) - 1) << 16); | 1156 | data |= (((size / 16) - 1) << 16); |
1151 | data |= (0 << 23); | 1157 | data |= (0 << 23); |
1152 | data |= 8; | 1158 | data |= 8; |
1153 | writel(data, mmio + PDC_DIMM0_CONTROL_OFFSET); | 1159 | writel(data, mmio + PDC_DIMM0_CONTROL_OFFSET); |
1154 | readl(mmio + PDC_DIMM0_CONTROL_OFFSET); | 1160 | readl(mmio + PDC_DIMM0_CONTROL_OFFSET); |
1155 | return size; | 1161 | return size; |
1156 | } | 1162 | } |
1157 | 1163 | ||
1158 | 1164 | ||
@@ -1172,12 +1178,12 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe) | |||
1172 | Refresh Enable (bit 17) | 1178 | Refresh Enable (bit 17) |
1173 | */ | 1179 | */ |
1174 | 1180 | ||
1175 | data = 0x022259F1; | 1181 | data = 0x022259F1; |
1176 | writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); | 1182 | writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); |
1177 | readl(mmio + PDC_SDRAM_CONTROL_OFFSET); | 1183 | readl(mmio + PDC_SDRAM_CONTROL_OFFSET); |
1178 | 1184 | ||
1179 | /* Turn on for ECC */ | 1185 | /* Turn on for ECC */ |
1180 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, | 1186 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, |
1181 | PDC_DIMM_SPD_TYPE, &spd0); | 1187 | PDC_DIMM_SPD_TYPE, &spd0); |
1182 | if (spd0 == 0x02) { | 1188 | if (spd0 == 0x02) { |
1183 | data |= (0x01 << 16); | 1189 | data |= (0x01 << 16); |
@@ -1191,22 +1197,22 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe) | |||
1191 | data |= (1<<19); | 1197 | data |= (1<<19); |
1192 | writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); | 1198 | writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); |
1193 | 1199 | ||
1194 | error = 1; | 1200 | error = 1; |
1195 | for (i = 1; i <= 10; i++) { /* polling ~5 secs */ | 1201 | for (i = 1; i <= 10; i++) { /* polling ~5 secs */ |
1196 | data = readl(mmio + PDC_SDRAM_CONTROL_OFFSET); | 1202 | data = readl(mmio + PDC_SDRAM_CONTROL_OFFSET); |
1197 | if (!(data & (1<<19))) { | 1203 | if (!(data & (1<<19))) { |
1198 | error = 0; | 1204 | error = 0; |
1199 | break; | 1205 | break; |
1200 | } | 1206 | } |
1201 | msleep(i*100); | 1207 | msleep(i*100); |
1202 | } | 1208 | } |
1203 | return error; | 1209 | return error; |
1204 | } | 1210 | } |
1205 | 1211 | ||
1206 | 1212 | ||
1207 | static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | 1213 | static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) |
1208 | { | 1214 | { |
1209 | int speed, size, length; | 1215 | int speed, size, length; |
1210 | u32 addr,spd0,pci_status; | 1216 | u32 addr,spd0,pci_status; |
1211 | u32 tmp=0; | 1217 | u32 tmp=0; |
1212 | u32 time_period=0; | 1218 | u32 time_period=0; |
@@ -1233,7 +1239,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | |||
1233 | /* Wait 3 seconds */ | 1239 | /* Wait 3 seconds */ |
1234 | msleep(3000); | 1240 | msleep(3000); |
1235 | 1241 | ||
1236 | /* | 1242 | /* |
1237 | When timer is enabled, counter is decreased every internal | 1243 | When timer is enabled, counter is decreased every internal |
1238 | clock cycle. | 1244 | clock cycle. |
1239 | */ | 1245 | */ |
@@ -1241,24 +1247,24 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | |||
1241 | tcount = readl(mmio + PDC_TIME_COUNTER); | 1247 | tcount = readl(mmio + PDC_TIME_COUNTER); |
1242 | VPRINTK("Time Counter Register (0x44): 0x%x\n", tcount); | 1248 | VPRINTK("Time Counter Register (0x44): 0x%x\n", tcount); |
1243 | 1249 | ||
1244 | /* | 1250 | /* |
1245 | If SX4 is on PCI-X bus, after 3 seconds, the timer counter | 1251 | If SX4 is on PCI-X bus, after 3 seconds, the timer counter |
1246 | register should be >= (0xffffffff - 3x10^8). | 1252 | register should be >= (0xffffffff - 3x10^8). |
1247 | */ | 1253 | */ |
1248 | if(tcount >= PCI_X_TCOUNT) { | 1254 | if(tcount >= PCI_X_TCOUNT) { |
1249 | ticks = (time_period - tcount); | 1255 | ticks = (time_period - tcount); |
1250 | VPRINTK("Num counters 0x%x (%d)\n", ticks, ticks); | 1256 | VPRINTK("Num counters 0x%x (%d)\n", ticks, ticks); |
1251 | 1257 | ||
1252 | clock = (ticks / 300000); | 1258 | clock = (ticks / 300000); |
1253 | VPRINTK("10 * Internal clk = 0x%x (%d)\n", clock, clock); | 1259 | VPRINTK("10 * Internal clk = 0x%x (%d)\n", clock, clock); |
1254 | 1260 | ||
1255 | clock = (clock * 33); | 1261 | clock = (clock * 33); |
1256 | VPRINTK("10 * Internal clk * 33 = 0x%x (%d)\n", clock, clock); | 1262 | VPRINTK("10 * Internal clk * 33 = 0x%x (%d)\n", clock, clock); |
1257 | 1263 | ||
1258 | /* PLL F Param (bit 22:16) */ | 1264 | /* PLL F Param (bit 22:16) */ |
1259 | fparam = (1400000 / clock) - 2; | 1265 | fparam = (1400000 / clock) - 2; |
1260 | VPRINTK("PLL F Param: 0x%x (%d)\n", fparam, fparam); | 1266 | VPRINTK("PLL F Param: 0x%x (%d)\n", fparam, fparam); |
1261 | 1267 | ||
1262 | /* OD param = 0x2 (bit 31:30), R param = 0x5 (bit 29:25) */ | 1268 | /* OD param = 0x2 (bit 31:30), R param = 0x5 (bit 29:25) */ |
1263 | pci_status = (0x8a001824 | (fparam << 16)); | 1269 | pci_status = (0x8a001824 | (fparam << 16)); |
1264 | } else | 1270 | } else |
@@ -1269,21 +1275,21 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | |||
1269 | writel(pci_status, mmio + PDC_CTL_STATUS); | 1275 | writel(pci_status, mmio + PDC_CTL_STATUS); |
1270 | readl(mmio + PDC_CTL_STATUS); | 1276 | readl(mmio + PDC_CTL_STATUS); |
1271 | 1277 | ||
1272 | /* | 1278 | /* |
1273 | Read SPD of DIMM by I2C interface, | 1279 | Read SPD of DIMM by I2C interface, |
1274 | and program the DIMM Module Controller. | 1280 | and program the DIMM Module Controller. |
1275 | */ | 1281 | */ |
1276 | if (!(speed = pdc20621_detect_dimm(pe))) { | 1282 | if (!(speed = pdc20621_detect_dimm(pe))) { |
1277 | printk(KERN_ERR "Detect Local DIMM Fail\n"); | 1283 | printk(KERN_ERR "Detect Local DIMM Fail\n"); |
1278 | return 1; /* DIMM error */ | 1284 | return 1; /* DIMM error */ |
1279 | } | 1285 | } |
1280 | VPRINTK("Local DIMM Speed = %d\n", speed); | 1286 | VPRINTK("Local DIMM Speed = %d\n", speed); |
1281 | 1287 | ||
1282 | /* Programming DIMM0 Module Control Register (index_CID0:80h) */ | 1288 | /* Programming DIMM0 Module Control Register (index_CID0:80h) */ |
1283 | size = pdc20621_prog_dimm0(pe); | 1289 | size = pdc20621_prog_dimm0(pe); |
1284 | VPRINTK("Local DIMM Size = %dMB\n",size); | 1290 | VPRINTK("Local DIMM Size = %dMB\n",size); |
1285 | 1291 | ||
1286 | /* Programming DIMM Module Global Control Register (index_CID0:88h) */ | 1292 | /* Programming DIMM Module Global Control Register (index_CID0:88h) */ |
1287 | if (pdc20621_prog_dimm_global(pe)) { | 1293 | if (pdc20621_prog_dimm_global(pe)) { |
1288 | printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n"); | 1294 | printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n"); |
1289 | return 1; | 1295 | return 1; |
@@ -1302,30 +1308,30 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | |||
1302 | 1308 | ||
1303 | pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40); | 1309 | pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40); |
1304 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); | 1310 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); |
1305 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], | 1311 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], |
1306 | test_parttern2[1], &(test_parttern2[2])); | 1312 | test_parttern2[1], &(test_parttern2[2])); |
1307 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040, | 1313 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040, |
1308 | 40); | 1314 | 40); |
1309 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], | 1315 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], |
1310 | test_parttern2[1], &(test_parttern2[2])); | 1316 | test_parttern2[1], &(test_parttern2[2])); |
1311 | 1317 | ||
1312 | pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40); | 1318 | pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40); |
1313 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); | 1319 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); |
1314 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], | 1320 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], |
1315 | test_parttern2[1], &(test_parttern2[2])); | 1321 | test_parttern2[1], &(test_parttern2[2])); |
1316 | } | 1322 | } |
1317 | #endif | 1323 | #endif |
1318 | 1324 | ||
1319 | /* ECC initiliazation. */ | 1325 | /* ECC initiliazation. */ |
1320 | 1326 | ||
1321 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, | 1327 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, |
1322 | PDC_DIMM_SPD_TYPE, &spd0); | 1328 | PDC_DIMM_SPD_TYPE, &spd0); |
1323 | if (spd0 == 0x02) { | 1329 | if (spd0 == 0x02) { |
1324 | VPRINTK("Start ECC initialization\n"); | 1330 | VPRINTK("Start ECC initialization\n"); |
1325 | addr = 0; | 1331 | addr = 0; |
1326 | length = size * 1024 * 1024; | 1332 | length = size * 1024 * 1024; |
1327 | while (addr < length) { | 1333 | while (addr < length) { |
1328 | pdc20621_put_to_dimm(pe, (void *) &tmp, addr, | 1334 | pdc20621_put_to_dimm(pe, (void *) &tmp, addr, |
1329 | sizeof(u32)); | 1335 | sizeof(u32)); |
1330 | addr += sizeof(u32); | 1336 | addr += sizeof(u32); |
1331 | } | 1337 | } |