Commit fa38fd4c22e3bac81965467ebb7e902102744c5d

kanoi 2014-05-08T00:48:02

minion - allow setting the frequency

diff --git a/ASIC-README b/ASIC-README
index 6e82783..e68837c 100644
--- a/ASIC-README
+++ b/ASIC-README
@@ -7,6 +7,7 @@ Currently supported devices include:
 - BF1 (bitfury) USB (red and blue)
 - KnCminer Mercury, Saturn and Jupiter
 - BlackArrow Bitfury
+- BlackArrow Minion
 - Bi*fury USB
 - Onestring miner USB
 - Hexfury USB
@@ -55,6 +56,14 @@ The current BlackArrow Bitfury devices are similar to the Bitfury GPIO mining
 boards, with both V1 and V2 controllers, and come up as BaB.
 
 
+BlackArrow Minion devices
+
+BlackArrow Minion devices need the --enable-minion option when compiling
+cgminer.
+
+BlackArrow Minion devices are SPI/GPIO mining devices and come up as MBA
+
+
 BITFURY devices
 
 Bitfury devices need the --enable-bitfury option when compiling cgminer.
@@ -225,6 +234,7 @@ ASIC SPECIFIC COMMANDS
 --hfa-temp-overheat <arg> Set the hashfast overheat throttling temperature (default: 95)
 --hfa-temp-target <arg> Set the hashfast target temperature (0 to disable) (default: 88)
 --klondike-options <arg> Set klondike options clock:temptarget
+--minion-freq <arg> Set minion chip frequencies in MHz, single value or comma list, range 100-1400 (default: 1000)
 --nfu-bits <arg>    Set nanofury bits for overclocking, range 32-63 (default: 50)
 
 
diff --git a/README b/README
index 7e59bd7..c3eb8d6 100644
--- a/README
+++ b/README
@@ -218,6 +218,7 @@ Options for both config file and command line:
 --load-balance      Change multipool strategy from failover to quota based balance
 --log|-l <arg>      Interval in seconds between log output (default: 5)
 --lowmem            Minimise caching of shares for low memory applications
+--minion-freq <arg> Set minion chip frequencies in MHz, single value or comma list, range 100-1400 (default: 1000)
 --monitor|-m <arg>  Use custom pipe cmd for output messages
 --nfu-bits <arg>    Set nanofury bits for overclocking, range 32-63 (default: 50)
 --net-delay         Impose small delays in networking to not overload slow routers
diff --git a/cgminer.c b/cgminer.c
index e77da7f..6ce58af 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -238,6 +238,9 @@ static char *opt_set_bitmain_freq;
 static char *opt_set_hfa_fan;
 #endif
 static char *opt_set_null;
+#ifdef USE_MINION
+char *opt_minion_freq;
+#endif
 
 #ifdef USE_USBUTILS
 char *opt_usb_select = NULL;
@@ -1309,6 +1312,11 @@ static struct opt_table opt_config_table[] = {
 	OPT_WITHOUT_ARG("--lowmem",
 			opt_set_bool, &opt_lowmem,
 			"Minimise caching of shares for low memory applications"),
+#ifdef USE_MINION
+	OPT_WITH_ARG("--minion-freq",
+		     opt_set_charp, NULL, &opt_minion_freq,
+		     "Set minion chip frequencies in MHz, single value or comma list, range 100-1400 (default: 1000)"),
+#endif
 #if defined(unix) || defined(__APPLE__)
 	OPT_WITH_ARG("--monitor|-m",
 		     opt_set_charp, NULL, &opt_stderr_cmd,
diff --git a/driver-minion.c b/driver-minion.c
index c0f6102..c23af47 100644
--- a/driver-minion.c
+++ b/driver-minion.c
@@ -10,6 +10,8 @@
 #include "config.h"
 #include "compat.h"
 #include "miner.h"
+#include <ctype.h>
+#include <math.h>
 
 #ifndef LINUX
 static void minion_detect(__maybe_unused bool hotplug)
@@ -211,7 +213,9 @@ struct minion_header {
 #define MINION_CHIP_SIG_SHIFT4 (((MINION_CHIP_SIG & 0xffff0000) >> 16) & 0x0000ffff)
 
 #define MINION_FREQ_MIN 1
+#define MINION_FREQ_DEF 10
 #define MINION_FREQ_MAX 14
+#define MINION_FREQ_FACTOR 100
 
 static uint32_t minion_freq[] = {
 	0x0,
@@ -533,6 +537,7 @@ struct minion_info {
 	// TODO: need to track disabled chips - done?
 	int chips;
 	bool chip[MINION_CHIPS];
+	int init_freq[MINION_CHIPS];
 
 	uint32_t next_task_id;
 
@@ -1089,12 +1094,13 @@ static int build_cmd(struct cgpu_info *minioncgpu, struct minion_info *minioninf
 	return reply;
 }
 
-// TODO: hard coded for now
 static void init_chip(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int chip)
 {
 	uint8_t rbuf[MINION_BUFSIZ];
 	uint8_t data[4];
 	__maybe_unused int reply;
+	int choice;
+	uint32_t freq;
 
 	// Complete chip reset
 	data[0] = 0x00;
@@ -1125,6 +1131,20 @@ static void init_chip(struct cgpu_info *minioncgpu, struct minion_info *minionin
 	reply = build_cmd(minioncgpu, minioninfo,
 			  chip, WRITE_ADDR(MINION_SYS_MISC_CTL),
 			  rbuf, 0, data);
+
+	// Set chip frequency
+	choice = minioninfo->init_freq[chip];
+	if (choice < MINION_FREQ_MIN || choice > MINION_FREQ_MAX)
+		choice = MINION_FREQ_DEF;
+	freq = minion_freq[choice];
+	data[0] = (uint8_t)(freq & 0xff);
+	data[1] = (uint8_t)(((freq & 0xff00) >> 8) & 0xff);
+	data[2] = (uint8_t)(((freq & 0xff0000) >> 16) & 0xff);
+	data[3] = (uint8_t)(((freq & 0xff000000) >> 24) & 0xff);
+
+	reply = build_cmd(minioncgpu, minioninfo,
+			  chip, WRITE_ADDR(MINION_SYS_FREQ_CTL),
+			  rbuf, 0, data);
 }
 
 // TODO: hard coded for now
@@ -1598,6 +1618,40 @@ static bool minion_init_gpio_interrupt(struct cgpu_info *minioncgpu, struct mini
 	return true;
 }
 
+static void minion_process_options(struct minion_info *minioninfo)
+{
+	int last_freq = MINION_FREQ_DEF;
+	char *freq, *comma, *buf;
+	int i;
+
+	if (opt_minion_freq && *opt_minion_freq) {
+		buf = freq = strdup(opt_minion_freq);
+		comma = strchr(freq, ',');
+		if (comma)
+			*(comma++) = '\0';
+
+		for (i = 0; i < MINION_CHIPS; i++) {
+			if (freq && isdigit(*freq)) {
+				last_freq = (int)round((double)atoi(freq) / (double)MINION_FREQ_FACTOR);
+				if (last_freq < MINION_FREQ_MIN)
+					last_freq = MINION_FREQ_MIN;
+				if (last_freq > MINION_FREQ_MAX)
+					last_freq = MINION_FREQ_MAX;
+
+				freq = comma;
+				if (comma) {
+					comma = strchr(freq, ',');
+					if (comma)
+						*(comma++) = '\0';
+				}
+			}
+			minioninfo->init_freq[i] = last_freq;
+		}
+
+		free(buf);
+	}
+}
+
 static void minion_detect(bool hotplug)
 {
 	struct cgpu_info *minioncgpu = NULL;
@@ -1629,6 +1683,11 @@ static void minion_detect(bool hotplug)
 	mutex_init(&(minioninfo->spi_lock));
 	mutex_init(&(minioninfo->sta_lock));
 
+	for (i = 0; i < MINION_CHIPS; i++)
+		minioninfo->init_freq[i] = MINION_FREQ_DEF;
+
+	minion_process_options(minioninfo);
+
 	applog(LOG_WARNING, "%s: checking for chips ...", minioncgpu->drv->dname);
 
 	minion_detect_chips(minioncgpu, minioninfo);
diff --git a/miner.h b/miner.h
index f25dc78..14f4877 100644
--- a/miner.h
+++ b/miner.h
@@ -1009,6 +1009,9 @@ extern char *opt_bitmine_a1_options;
 extern char *opt_bitmain_options;
 extern bool opt_bitmain_hwerror;
 #endif
+#ifdef USE_MINION
+extern char *opt_minion_freq;
+#endif
 #ifdef USE_USBUTILS
 extern char *opt_usb_select;
 extern int opt_usbdump;