Browse Source

Merge commit '80bfd5f' into bfgminer

Luke Dashjr 12 years ago
parent
commit
137f6d1cdb
1 changed files with 114 additions and 131 deletions
  1. 114 131
      driver-drillbit.c

+ 114 - 131
driver-drillbit.c

@@ -21,7 +21,7 @@
 BFG_REGISTER_DRIVER(drillbit_drv)
 
 #define DRILLBIT_MIN_VERSION 2
-#define DRILLBIT_MAX_VERSION 3
+#define DRILLBIT_MAX_VERSION 4
 
 #define DRILLBIT_MAX_WORK_RESULTS 0x400
 #define DRILLBIT_MAX_RESULT_NONCES 0x10
@@ -31,22 +31,15 @@ enum drillbit_capability {
 	DBC_EXT_CLOCK = 2,
 };
 
-enum drillbit_voltagecfg {
-	DBV_650mV = 0,
-	DBV_750mV = 2,
-	DBV_850mV = 1,
-	DBV_950mV = 3,
-};
-
 struct drillbit_board {
-	enum drillbit_voltagecfg core_voltage_cfg;
-	unsigned clock_level;
+	unsigned core_voltage;
+	unsigned clock_freq;
 	bool clock_div2;
 	bool use_ext_clock;
-	unsigned ext_clock_freq;
 	bool need_reinit;
 	bool trigger_identify;
 	uint16_t caps;
+	uint8_t protover;
 };
 
 static
@@ -84,7 +77,7 @@ err:
 	char * const product = (void*)&buf[1];
 	buf[9] = '\0';  // Ensure it is null-terminated (clobbers serial, but we already parsed it)
 	unsigned chips = buf[0xd];
-	uint16_t caps = (uint16_t)buf[0xe] | ((uint16_t)buf[0xf] << 8);
+	uint16_t caps = buf[0xe] | ((uint16_t)buf[0xf] << 8);
 	if (!product[0])
 		applogr(false, LOG_DEBUG, "%s: %s: Null product name", __func__, devpath);
 	if (!serialno)
@@ -102,7 +95,7 @@ err:
 			strcpy(product, "Eight");
 	}
 	else
-	if (chips == 8 && !strcmp(product, "Eight"))
+	if ((chips >= 8) && (chips <= 64) && (chips % 8 == 0) && !strcmp(product, "Eight"))
 	{}  // Known device
 	else
 	if (chips == 1 && !strcmp(product, "Thumb"))
@@ -134,6 +127,8 @@ err:
 	if (serial_claim_v(devpath, &drillbit_drv))
 		return false;
 	
+	intptr_t device_data = caps | ((intptr_t)protover << 16); // Store capabilities & protocol version in device_data, temporarily
+
 	struct cgpu_info * const cgpu = malloc(sizeof(*cgpu));
 	*cgpu = (struct cgpu_info){
 		.drv = &drillbit_drv,
@@ -143,7 +138,7 @@ err:
 		.deven = DEV_ENABLED,
 		.procs = chips,
 		.threads = 1,
-		.device_data = (void*)(intptr_t)caps,
+		.device_data = (void *)device_data,
 	};
 	return add_cgpu(cgpu);
 }
@@ -206,8 +201,34 @@ bool drillbit_send_config(struct cgpu_info * const dev)
 		return false;
 	
 	const struct drillbit_board * const board = dev->device_data;
-	const uint8_t buf[7] = {'C', board->core_voltage_cfg, board->clock_level, (board->clock_div2 ? 1 : 0), (board->use_ext_clock ? 1 : 0), (board->ext_clock_freq & 0xff), (board->ext_clock_freq >> 8)};
-	
+	uint8_t buf[7] = {'C'};
+	if(board->protover < 4) {
+		if(board->core_voltage < 750)
+			buf[1] = 0; // 650mV
+		else if(board->core_voltage < 850)
+			buf[1] = 1; // 750mV
+		else if(board->core_voltage < 950)
+			buf[1] = 2; // 850mV
+		else
+			buf[1] = 3; // 950mV
+		if(board->clock_freq < 64) // internal clock level, either direct or MHz/5
+			buf[2] = board->clock_freq;
+		else
+			buf[2] = board->clock_freq / 5;
+		buf[3] = board->clock_div2 ? 1 : 0;
+		buf[4] = board->use_ext_clock ? 1 : 0;
+		buf[5] = board->clock_freq;
+		buf[6] = board->clock_freq >> 8;
+	}
+	else {
+		buf[1] = board->core_voltage;
+		buf[2] = board->core_voltage >> 8;
+		buf[3] = board->clock_freq;
+		buf[4] = board->clock_freq >> 8;
+		buf[5] = board->clock_div2 ? 1 : 0;
+		buf[6] = board->use_ext_clock ? 1 : 0;
+	}
+
 	if (sizeof(buf) != write(fd, buf, sizeof(buf)))
 		problem(false, LOG_ERR, "%s: Error sending config", dev->dev_repr);
 	
@@ -260,14 +281,17 @@ bool drillbit_init(struct thr_info * const master_thr)
 	struct cgpu_info * const dev = master_thr->cgpu;
 	
 	dev->device_fd = -1;
+
+	intptr_t device_data = (intptr_t)dev->device_data; // capabilities & protocol version stored here
+
 	struct drillbit_board * const board = malloc(sizeof(*board));
 	*board = (struct drillbit_board){
-		.core_voltage_cfg = DBV_850mV,
-		.clock_level = 40,
+		.core_voltage = 850,
+		.clock_freq = 200,
 		.clock_div2 = false,
 		.use_ext_clock = false,
-		.ext_clock_freq = 200,
-		.caps = (intptr_t)dev->device_data,
+		.caps = device_data,
+		.protover = device_data >> 16,
 	};
 	dev->device_data = board;
 	
@@ -396,75 +420,77 @@ bool drillbit_get_work_results(struct cgpu_info * const dev)
 	uint32_t total;
 	int i, j;
 	
-	if (1 != write(fd, "E", 1))
-		problem(false, LOG_ERR, "%s: Error sending request for work results", dev->dev_repr);
+	do {
+		if (1 != write(fd, "E", 1))
+			problem(false, LOG_ERR, "%s: Error sending request for work results", dev->dev_repr);
 	
-	if (sizeof(total) != serial_read(fd, &total, sizeof(total)))
-		problem(false, LOG_ERR, "%s: Short read in response to 'E'", dev->dev_repr);
-	total = le32toh(total);
+		if (sizeof(total) != serial_read(fd, &total, sizeof(total)))
+			problem(false, LOG_ERR, "%s: Short read in response to 'E'", dev->dev_repr);
+		total = le32toh(total);
 	
-	if (total > DRILLBIT_MAX_WORK_RESULTS)
-		problem(false, LOG_ERR, "%s: Impossible number of total work: %lu",
-		        dev->dev_repr, (unsigned long)total);
+		if (total > DRILLBIT_MAX_WORK_RESULTS)
+			problem(false, LOG_ERR, "%s: Impossible number of total work: %lu",
+				dev->dev_repr, (unsigned long)total);
 	
-	for (i = 0; i < total; ++i)
-	{
-		if (sizeof(buf) != serial_read(fd, buf, sizeof(buf)))
-			problem(false, LOG_ERR, "%s: Short read on %dth total work",
-			        dev->dev_repr, i);
-		const int chipid = buf[0];
-		struct cgpu_info * const proc = drillbit_find_proc(dev, chipid);
-		struct thr_info * const thr = proc->thr[0];
-		if (unlikely(!proc))
-		{
-			applog(LOG_ERR, "%s: Unknown chip id %d", dev->dev_repr, chipid);
-			continue;
-		}
-		const bool is_idle = buf[3];
-		int nonces = buf[2];
-		if (nonces > DRILLBIT_MAX_RESULT_NONCES)
-		{
-			applog(LOG_ERR, "%"PRIpreprv": More than %d nonces claimed, impossible",
-			       proc->proc_repr, (int)DRILLBIT_MAX_RESULT_NONCES);
-			nonces = DRILLBIT_MAX_RESULT_NONCES;
-		}
-		applog(LOG_DEBUG, "%"PRIpreprv": Handling completion of %d nonces. is_idle=%d work=%p next_work=%p",
-		       proc->proc_repr, nonces, is_idle, thr->work, thr->next_work);
-		const uint32_t *nonce_p = (void*)&buf[4];
-		for (j = 0; j < nonces; ++j, ++nonce_p)
+		for (i = 0; i < total; ++i)
 		{
-			uint32_t nonce = bitfury_decnonce(*nonce_p);
-			if (bitfury_fudge_nonce2(thr->work, &nonce))
-				submit_nonce(thr, thr->work, nonce);
-			else
-			if (bitfury_fudge_nonce2(thr->next_work, &nonce))
+			if (sizeof(buf) != serial_read(fd, buf, sizeof(buf)))
+				problem(false, LOG_ERR, "%s: Short read on %dth total work",
+					dev->dev_repr, i);
+			const int chipid = buf[0];
+			struct cgpu_info * const proc = drillbit_find_proc(dev, chipid);
+			struct thr_info * const thr = proc->thr[0];
+			if (unlikely(!proc))
 			{
-				applog(LOG_DEBUG, "%"PRIpreprv": Result for next work, transitioning",
-				       proc->proc_repr);
-				submit_nonce(thr, thr->next_work, nonce);
-				mt_job_transition(thr);
-				job_start_complete(thr);
+				applog(LOG_ERR, "%s: Unknown chip id %d", dev->dev_repr, chipid);
+				continue;
 			}
-			else
-			if (bitfury_fudge_nonce2(thr->prev_work, &nonce))
+			const bool is_idle = buf[3];
+			int nonces = buf[2];
+			if (nonces > DRILLBIT_MAX_RESULT_NONCES)
 			{
-				applog(LOG_DEBUG, "%"PRIpreprv": Result for PREVIOUS work",
-				       proc->proc_repr);
-				submit_nonce(thr, thr->prev_work, nonce);
+				applog(LOG_ERR, "%"PRIpreprv": More than %d nonces claimed, impossible",
+					proc->proc_repr, (int)DRILLBIT_MAX_RESULT_NONCES);
+				nonces = DRILLBIT_MAX_RESULT_NONCES;
 			}
-			else
-				inc_hw_errors(thr, thr->work, nonce);
-		}
-		if (is_idle && thr->next_work)
-		{
-			applog(LOG_DEBUG, "%"PRIpreprv": Chip went idle without any results for next work",
-			       proc->proc_repr);
-			mt_job_transition(thr);
-			job_start_complete(thr);
+			applog(LOG_DEBUG, "%"PRIpreprv": Handling completion of %d nonces from chip %d. is_idle=%d work=%p next_work=%p",
+				proc->proc_repr, nonces, chipid, is_idle, thr->work, thr->next_work);
+			const uint32_t *nonce_p = (void*)&buf[4];
+			for (j = 0; j < nonces; ++j, ++nonce_p)
+			{
+				uint32_t nonce = bitfury_decnonce(*nonce_p);
+				if (bitfury_fudge_nonce2(thr->work, &nonce))
+					submit_nonce(thr, thr->work, nonce);
+				else
+					if (bitfury_fudge_nonce2(thr->next_work, &nonce))
+					{
+						applog(LOG_DEBUG, "%"PRIpreprv": Result for next work, transitioning",
+							proc->proc_repr);
+						submit_nonce(thr, thr->next_work, nonce);
+						mt_job_transition(thr);
+						job_start_complete(thr);
+					}
+					else
+						if (bitfury_fudge_nonce2(thr->prev_work, &nonce))
+						{
+							applog(LOG_DEBUG, "%"PRIpreprv": Result for PREVIOUS work",
+								proc->proc_repr);
+							submit_nonce(thr, thr->prev_work, nonce);
+						}
+						else
+							inc_hw_errors(thr, thr->work, nonce);
+			}
+			if (is_idle && thr->next_work)
+			{
+				applog(LOG_DEBUG, "%"PRIpreprv": Chip went idle without any results for next work",
+					proc->proc_repr);
+				mt_job_transition(thr);
+				job_start_complete(thr);
+			}
+			if (!thr->next_work)
+				timer_set_now(&thr->tv_morework);
 		}
-		if (!thr->next_work)
-			timer_set_now(&thr->tv_morework);
-	}
+	} while(total > 0);
 	
 	return true;
 }
@@ -538,26 +564,10 @@ bool drillbit_get_stats(struct cgpu_info * const dev)
 	return true;
 }
 
-static
-float drillbit_voltagecfg_volts(const enum drillbit_voltagecfg vcfg)
-{
-	switch (vcfg)
-	{
-		case DBV_650mV: return 0.65;
-		case DBV_750mV: return 0.75;
-		case DBV_850mV: return 0.85;
-		case DBV_950mV: return 0.95;
-	}
-	return 0;
-}
-
 static
 void drillbit_clockcfg_str(char * const buf, size_t bufsz, struct drillbit_board * const board)
 {
-	if (board->use_ext_clock)
-		snprintf(buf, bufsz, "%u", board->ext_clock_freq);
-	else
-		snprintf(buf, bufsz, "L%u", board->clock_level);
+	snprintf(buf, bufsz, "%u", board->clock_freq);
 	if (board->clock_div2)
 		tailsprintf(buf, bufsz, ":2");
 }
@@ -573,7 +583,7 @@ struct api_data *drillbit_api_stats(struct cgpu_info * const proc)
 	drillbit_clockcfg_str(buf, sizeof(buf), board);
 	root = api_add_string(root, "ClockCfg", buf, true);
 	
-	float volts = drillbit_voltagecfg_volts(board->core_voltage_cfg);
+	float volts = board->core_voltage / 1000.0;
 	root = api_add_volts(root, "Voltage", &volts, true);
 	
 	return root;
@@ -601,26 +611,7 @@ char *drillbit_set_device(struct cgpu_info * const proc, char * const option, ch
 		if (!setting || !*setting)
 			return "Missing voltage setting";
 		const int val = atof(setting) * 1000;
-		enum drillbit_voltagecfg vcfg;
-		switch (val)
-		{
-			case 650: case 649:
-				vcfg = DBV_650mV;
-				break;
-			case 750: case 749:
-				vcfg = DBV_750mV;
-				break;
-			case 850: case 849:
-				vcfg = DBV_850mV;
-				break;
-			case 950: case 949:
-				vcfg = DBV_950mV;
-				break;
-			default:
-				return "Invalid voltage value";
-		}
-		
-		board->core_voltage_cfg = vcfg;
+		board->core_voltage = val;
 		board->need_reinit = true;
 		
 		return NULL;
@@ -638,20 +629,12 @@ char *drillbit_set_device(struct cgpu_info * const proc, char * const option, ch
 		{
 			if (!(board->caps & DBC_EXT_CLOCK))
 				return "External clock not supported by this device";
-			if (num < 0 || num > 0xffff)
-				return "External clock frequency out of range (0-65535)";
-			board->clock_div2 = div2;
-			board->ext_clock_freq = num;
 			board->use_ext_clock = true;
 		}
-		else
-		{
-			if (num < 0 || num > 63)
-				return "Internal clock level out of range (0-63)";
-			board->clock_div2 = div2;
-			board->clock_level = num;
-			board->use_ext_clock = false;
-		}
+		if (num < 0 || num > 0xffff)
+			return "Clock frequency out of range (0-65535)";
+		board->clock_div2 = div2;
+		board->clock_freq = num;
 		board->need_reinit = true;
 		return NULL;
 	}
@@ -692,7 +675,7 @@ void drillbit_wlogprint_status(struct cgpu_info * const proc)
 	
 	drillbit_clockcfg_str(buf, sizeof(buf), board);
 	wlogprint("Clock: %s\n", buf);
-	wlogprint("Voltage: %.2f\n", drillbit_voltagecfg_volts(board->core_voltage_cfg));
+	wlogprint("Voltage: %.2f\n", board->core_voltage / 1000.0);
 }
 #endif