Browse Source

bitfury: Reorganize polling to hit chips sequentially, so SPI traffic can be minimised

Luke Dashjr 12 years ago
parent
commit
a49bda147e
4 changed files with 75 additions and 16 deletions
  1. 2 1
      driver-bfsb.c
  2. 69 14
      driver-bitfury.c
  3. 1 0
      driver-bitfury.h
  4. 3 1
      driver-metabank.c

+ 2 - 1
driver-bfsb.c

@@ -158,6 +158,7 @@ bool bfsb_init(struct thr_info *thr)
 	}
 	
 	free(devicelist);
+	timer_set_now(&thr->tv_poll);
 	
 	return true;
 }
@@ -209,7 +210,7 @@ struct device_drv bfsb_drv = {
 	.job_prepare = bitfury_job_prepare,
 	.thread_init = bfsb_init,
 	.poll = bitfury_do_io,
-	.job_start = bitfury_do_io,
+	.job_start = bitfury_noop_job_start,
 	.job_process_results = bitfury_job_process_results,
 	.get_api_extra_device_status = bfsb_api_device_status,
 	.thread_disable = bfsb_disable,

+ 69 - 14
driver-bitfury.c

@@ -454,25 +454,80 @@ bool fudge_nonce(struct work * const work, uint32_t *nonce_p) {
 	return false;
 }
 
-void bitfury_do_io(struct thr_info *thr)
+void bitfury_noop_job_start(struct thr_info __maybe_unused * const thr)
 {
-	struct cgpu_info * const proc = thr->cgpu;
-	struct bitfury_device * const bitfury = proc->device_data;
+}
+
+void bitfury_do_io(struct thr_info * const master_thr)
+{
+	struct cgpu_info *proc;
+	struct thr_info *thr;
+	struct bitfury_device *bitfury;
 	const uint32_t *inp;
-	uint32_t * const newbuf = &bitfury->newbuf[0];
-	uint32_t * const oldbuf = &bitfury->oldbuf[0];
-	int n, i;
+	int n, i, j;
 	bool newjob;
 	uint32_t nonce;
+	int n_chips = 0, lastchip;
+	struct spi_port *spi = NULL;
+	bool should_be_running;
+	
+	for (proc = master_thr->cgpu; proc; proc = proc->next_proc)
+		++n_chips;
+	
+	struct cgpu_info *procs[n_chips];
+	void *rxbuf[n_chips];
+	
+	// NOTE: This code assumes:
+	// 1) that chips on the same SPI bus are grouped together
+	// 2) that chips are in sequential fasync order
+	n_chips = 0;
+	for (proc = master_thr->cgpu; proc; proc = proc->next_proc)
+	{
+		thr = proc->thr[0];
+		bitfury = proc->device_data;
+		
+		should_be_running = (proc->deven == DEV_ENABLED && !thr->pause);
+		
+		if (should_be_running)
+		{
+			if (spi != bitfury->spi)
+			{
+				if (spi)
+					spi_txrx(spi);
+				spi = bitfury->spi;
+				spi_clear_buf(spi);
+				spi_emit_break(spi);
+				lastchip = 0;
+			}
+			procs[n_chips] = proc;
+			spi_emit_fasync(spi, bitfury->fasync - lastchip);
+			lastchip = bitfury->fasync;
+			rxbuf[n_chips] = spi_emit_data(spi, 0x3000, &bitfury->atrvec[0], 19 * 4);
+			++n_chips;
+		}
+		else
+		if (thr->work /* is currently running */ && thr->busy_state != TBS_STARTING_JOB)
+			;//FIXME: shutdown chip
+	}
+	spi_txrx(spi);
 	
+	for (j = 0; j < n_chips; ++j)
+	{
+		proc = procs[j];
+		thr = proc->thr[0];
+		bitfury = proc->device_data;
+		uint32_t * const newbuf = &bitfury->newbuf[0];
+		uint32_t * const oldbuf = &bitfury->oldbuf[0];
+
 	if (unlikely(bitfury->desync_counter == 99))
 	{
+			// TODO: use current rxbuf
 		bitfury_init_oldbuf(proc);
 		goto out;
 	}
-	
-	inp = bitfury_just_io(bitfury);
-	
+
+		inp = rxbuf[j];
+
 	if (opt_debug)
 		bitfury_debug_nonce_array(proc, "Read", inp);
 	
@@ -489,7 +544,7 @@ void bitfury_do_io(struct thr_info *thr)
 			applog(LOG_WARNING, "%"PRIpreprv": Previous nonce mismatch (4th try), recalibrating",
 			       proc->proc_repr);
 			bitfury_init_oldbuf(proc);
-			goto out;
+			continue;
 		}
 		applog(LOG_DEBUG, "%"PRIpreprv": Previous nonce mismatch, ignoring response",
 		       proc->proc_repr);
@@ -562,14 +617,14 @@ void bitfury_do_io(struct thr_info *thr)
 	bitfury->oldjob = newjob;
 	
 out:
-	timer_set_delay_from_now(&thr->tv_poll, 10000);
+		continue;
+	}
+	
+	timer_set_delay_from_now(&master_thr->tv_poll, 10000);
 }
 
 int64_t bitfury_job_process_results(struct thr_info *thr, struct work *work, bool stopping)
 {
-	if (unlikely(stopping))
-		timer_unset(&thr->tv_poll);
-	
 	// Bitfury chips process only 768/1024 of the nonce range
 	return 0xbd000000;
 }

+ 1 - 0
driver-bitfury.h

@@ -12,6 +12,7 @@ extern bool bitfury_init_oldbuf(struct cgpu_info *);
 extern int64_t bitfury_scanHash(struct thr_info *);
 
 extern bool bitfury_job_prepare(struct thr_info *, struct work *, uint64_t max_nonce);
+extern void bitfury_noop_job_start(struct thr_info *);
 extern void bitfury_do_io(struct thr_info *);
 extern int64_t bitfury_job_process_results(struct thr_info *, struct work *, bool stopping);
 extern struct api_data *bitfury_api_device_status(const struct cgpu_info *);

+ 3 - 1
driver-metabank.c

@@ -156,6 +156,8 @@ bool metabank_init(struct thr_info *thr)
 			free(devicelist);
 	}
 	
+	timer_set_now(&thr->tv_poll);
+	
 	return true;
 }
 
@@ -212,7 +214,7 @@ struct device_drv metabank_drv = {
 #endif
 	.minerloop = minerloop_async,
 	.job_prepare = bitfury_job_prepare,
-	.job_start = bitfury_do_io,
+	.job_start = bitfury_noop_job_start,
 	.poll = bitfury_do_io,
 	.job_process_results = bitfury_job_process_results,