Bitcoin Forum
June 19, 2024, 01:35:11 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: [1]
1  Bitcoin / Hardware / Re: {BFL} Here's a LOOOOOOOOOOOOOOOOOOK at your Monarch! on: February 14, 2015, 05:56:32 AM
For BFL Monarch, I added experimental underclocking support to cgminer.

Example Usage: the following sets the clock frequency to max (1x), voltage at 580mV.

# cgminer --bflsc-volt=4 --bflsc-clock=16

Refer to BFL documentation for voltage levels, but please note I shifted the index by one; I needed '0' to mean 'do-nothing'. IE: the '16' above = 'F" in BFL docs.

As a safety precaution, cgminer will not initialize / use a Monarch unless the voltage and clock are set successfully. IE: a hotplug or power interruption will restore the voltage/clock settings to a Monarch before mining commences.

The patch below is against cgminer commit 8b425ed545d64f3007c6a7b2b70910efec65a7ea.
htt p s://github.com/ckolivas/cgminer/commit/8b425ed545d64f3007c6a7b2b70910efec65a7ea

----------------

diff --git a/cgminer.c b/cgminer.c
index 94e847e..48db62d 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -796,6 +796,16 @@ static char *set_int_1_to_10(const char *arg, int *i)
    return set_int_range(arg, i, 1, 10);
 }
 
+static char *set_int_0_to_32(const char *arg, int *i)
+{
+   return set_int_range(arg, i, 0, 32);
+}
+
+static char *set_int_0_to_16(const char *arg, int *i)
+{
+   return set_int_range(arg, i, 0, 16);
+}
+
 static char __maybe_unused *set_int_0_to_4(const char *arg, int *i)
 {
    return set_int_range(arg, i, 0, 4);
@@ -1265,6 +1275,12 @@ static struct opt_table opt_config_table[] = {
    OPT_WITH_ARG("--bflsc-overheat",
            set_int_0_to_200, opt_show_intval, &opt_bflsc_overheat,
            "Set overheat temperature where BFLSC devices throttle, 0 to disable"),
+   OPT_WITH_ARG("--bflsc-volt",
+           set_int_0_to_16, opt_show_intval, &opt_bflsc_volt,
+           "Set monarch voltage level (1-16), 0 to disable. BFL claims values above 7 are disabled."),
+   OPT_WITH_ARG("--bflsc-clock",
+           set_int_0_to_32, opt_show_intval, &opt_bflsc_clock,
+           "Set monarch clock speed (1-32), 0 to disable, 17-32 enable clock doubler"),
 #endif
 #ifdef USE_AVALON
    OPT_WITH_ARG("--bitburner-voltage",
diff --git a/driver-bflsc.c b/driver-bflsc.c
index ac77d48..7dfd10c 100644
--- a/driver-bflsc.c
+++ b/driver-bflsc.c
@@ -31,6 +31,15 @@
 #include "driver-bflsc.h"
 
 int opt_bflsc_overheat = BFLSC_TEMP_OVERHEAT;
+int opt_bflsc_clock = 0;
+int opt_bflsc_volt = 0;
+
+float bflsc_voltage_map[] = {
+  0.540, 0.550, 0.560, 0.580,
+  0.600, 0.620, 0.630, 0.643,
+  0.650, 0.662, 0.670, 0.680,
+  0.700, 0.720, 0.730, 0.750
+};
 
 static const char *blank = "";
 
@@ -453,6 +462,7 @@ static bool bflsc_qres(struct cgpu_info *bflsc, char *buf, size_t bufsiz, int de
 static void __bflsc_initialise(struct cgpu_info *bflsc)
 {
    int err, interface;
+   struct bflsc_info *sc_info = (struct bflsc_info *)(bflsc->device_data);
 
 // TODO: does x-link bypass the other device FTDI? (I think it does)
 //   So no initialisation required except for the master device?
@@ -536,6 +546,7 @@ static void __bflsc_initialise(struct cgpu_info *bflsc)
 
    if (!bflsc->cutofftemp)
       bflsc->cutofftemp = opt_bflsc_overheat;
+
 }
 
 static void bflsc_initialise(struct cgpu_info *bflsc)
@@ -555,6 +566,82 @@ static void bflsc_initialise(struct cgpu_info *bflsc)
    }
 }
 
+static bool __bflsc_set_volt(struct cgpu_info *bflsc) {
+   char msg[16];
+   char recv[100];
+   int err,amount;
+   bool sent;
+   int effective_volt;
+
+   if (!opt_bflsc_volt)
+      return true;
+
+   effective_volt=opt_bflsc_volt-1;
+
+   applogsiz(LOG_WARNING, BFLSC_APPLOGSIZ,
+      "%s (%s) set volt to %0.3fV (V%XX) ",
+      bflsc->drv->dname, bflsc->device_path,
+      bflsc_voltage_map[effective_volt], effective_volt);
+
+   snprintf(msg, sizeof(msg), "V%XX\n", effective_volt);
+   err = usb_write(bflsc, msg, strlen(msg), &amount, C_SETVOLT);
+   if (err < 0 || amount < 4) {
+      bflsc_applog(bflsc, 0, C_SETVOLT, amount, err);
+      return false;
+   }
+   err = usb_read_ok_timeout(bflsc, recv, sizeof(recv)-1, &amount, SET_VOLT_TIME_MAX_MS, C_REPLYSETVOLT);
+   if (err < 0 ) {
+      bflsc_applog(bflsc, 0, C_REPLYSETVOLT, amount, err);
+      return false;
+   }
+   return true;
+}
+
+static bool __bflsc_set_clock(struct cgpu_info *bflsc) {
+   char msg[16];
+   char recv[100];
+   int err,amount;
+   bool sent;
+   char double_clock_flag;
+   int effective_clock;
+
+   if (!opt_bflsc_clock)
+      return true;
+
+        effective_clock=opt_bflsc_clock-1;
+   double_clock_flag='X';
+
+   if (effective_clock > 15) {
+      double_clock_flag='D';
+      effective_clock &= 0x0F;
+      if (effective_clock > 2) {
+         applogsiz(LOG_WARNING, BFLSC_APPLOGSIZ,
+            "Frequency too high with clock doubling enabled; reducing frequency.");
+         effective_clock=2;
+         opt_bflsc_clock=19;
+      }
+   }
+
+   applogsiz(LOG_WARNING, BFLSC_APPLOGSIZ,
+      "%s (%s) set clock to %i (F%X%c)",
+      bflsc->drv->dname, bflsc->device_path,
+      opt_bflsc_clock, effective_clock, double_clock_flag);
+
+   snprintf(msg, sizeof(msg), "F%X%c\n", effective_clock, double_clock_flag);
+   err = usb_write(bflsc, msg, strlen(msg), &amount, C_SETCLOCK);
+   if (err < 0 || amount < 4) {
+      bflsc_applog(bflsc, 0, C_SETCLOCK, amount, err);
+      return false;
+   }
+   err = usb_read_ok_timeout(bflsc, recv, sizeof(recv)-1, &amount, SET_CLOCK_TIME_MAX_MS, C_REPLYSETCLOCK);
+   if (err < 0 ) {
+      bflsc_applog(bflsc, 0, C_REPLYSETCLOCK, amount, err);
+      return false;
+   }
+   return true;
+}
+
+
 static bool getinfo(struct cgpu_info *bflsc, int dev)
 {
    struct bflsc_info *sc_info = (struct bflsc_info *)(bflsc->device_data);
@@ -894,6 +981,15 @@ reinit:
    applog(LOG_DEBUG, "%s (%s) identified as: '%s'",
       bflsc->drv->dname, bflsc->device_path, bflsc->drv->name);
 
+   if (sc_info->ident == IDENT_BMA) {
+      if (!__bflsc_set_volt(bflsc))
+         goto unshin;
+      cgsleep_ms(100); // let voltage stabilize
+      if (!__bflsc_set_clock(bflsc))
+         goto unshin;
+      cgsleep_ms(100); // let clock stabilize
+   }
+
    if (!add_cgpu(bflsc))
       goto unshin;
 
diff --git a/driver-bflsc.h b/driver-bflsc.h
index 4778993..50789b0 100644
--- a/driver-bflsc.h
+++ b/driver-bflsc.h
@@ -386,7 +386,13 @@ struct SaveString {
 #define REINIT_TIME_MAX_MS 800
 // Keep trying up to this many us
 #define REINIT_TIME_MAX 3000000
+// How long do we wait for the voltage-set operation? (ms)
+#define SET_VOLT_TIME_MAX_MS 10000
+// How long do we wait for the clock-set operation? (ms)
+#define SET_CLOCK_TIME_MAX_MS 15000
 
 int opt_bflsc_overheat;
+int opt_bflsc_clock;
+int opt_bflsc_volt;
 
 #endif /* BFLSC_H */
Pages: [1]
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!