Browse Source

gc3355: Replace frequency-setting hex blobs with logic

Luke Dashjr 12 years ago
parent
commit
f6dacc4c8d
1 changed files with 96 additions and 192 deletions
  1. 96 192
      gc3355.c

+ 96 - 192
gc3355.c

@@ -10,7 +10,9 @@
 
 #include "gc3355.h"
 
+#include <stdint.h>
 #include <string.h>
+
 #include "miner.h"
 #include "icarus-common.h"
 #include "logging.h"
@@ -29,118 +31,6 @@
 #define DEFAULT_0_9V_sha2 "60"
 #define DEFAULT_1_2V_sha2 "0"
 
-static
-const char *pll_freq_1200M_cmd[] =
-{
-	"55AAEF000500E085",
-	"55AA0FFFB02800C0",
-	"",
-};
-
-static
-const char *pll_freq_1100M_cmd[] =
-{
-	"55AAEF0005006085",
-	"55AA0FFF4C2500C0",
-	"",
-};
-
-static
-const char *pll_freq_1000M_cmd[] =
-{
-	"55AAEF000500E084",
-	"55AA0FFFE82100C0",
-	"",
-};
-
-static
-const char *pll_freq_950M_cmd[] =
-{
-	"55AAEF000500A084",
-	"55AA0FFF362000C0",
-	"",
-};
-
-static
-const char *pll_freq_900M_cmd[] =
-{
-	"55AAEF0005006084",
-	"55AA0FFF841E00C0",
-	"",
-};
-
-static
-const char *pll_freq_850M_cmd[] =
-{
-	"55AAEF0005002084",
-	"55AA0FFFD21C00C0",
-	"",
-};
-
-static
-const char *pll_freq_800M_cmd[] =
-{
-	"55AAEF000500E083",
-	"55AA0FFF201B00C0",
-	"",
-};
-
-static
-const char *pll_freq_750M_cmd[] =
-{
-	"55AAEF000500A083",
-	"55AA0FFF6E1900C0",
-	"",
-};
-
-static
-const char *pll_freq_700M_cmd[] =
-{
-	"55AAEF0005006083",
-	"55AA0FFFBC1700C0",
-	"",
-};
-
-static
-const char *pll_freq_650M_cmd[] =
-{
-	"55AAEF0005002083",
-	"55AA0FFF0A1600C0",
-	"",
-};
-
-static
-const char *pll_freq_600M_cmd[] =
-{
-	"55AAEF000500E082",
-	"55AA0FFF581400C0",
-	"",
-};
-
-static
-const char *pll_freq_550M_cmd[] =
-{
-	"55AAEF000500A082",
-	"55AA0FFFA61200C0",
-	"",
-};
-
-static
-const char *pll_freq_500M_cmd[] =
-{
-	"55AAEF0005006082",
-	"55AA0FFFF41000C0",
-	"",
-};
-
-static
-const char *pll_freq_400M_cmd[] =
-{
-	"55AAEF000500E081",
-	"55AA0FFF900D00C0",
-	"",
-};
-
 static
 const char *sha2_gating[] =
 {
@@ -345,6 +235,83 @@ void gc3355_dual_reset(int fd)
 	set_serial_dtr(fd, 0);
 }
 
+static
+void gc3355_set_register(uint8_t * const buf, const uint8_t clusaddr, const uint8_t chipaddr, const uint8_t regaddr, const uint32_t val)
+{
+	buf[0] = 0x55;
+	buf[1] = 0xaa;
+	buf[2] = (clusaddr << 4) | chipaddr;
+	buf[3] = regaddr;
+	buf[4] = (val >>    0) & 0xff;
+	buf[5] = (val >>    8) & 0xff;
+	buf[6] = (val >> 0x10) & 0xff;
+	buf[7] = (val >> 0x18) & 0xff;
+}
+
+static
+void gc3355_config_cpm(uint8_t * const buf, const uint8_t chipaddr, const float mhz)
+{
+	// See https://github.com/gridseed/gc3355-doc/blob/master/GC3355_Register_Spec.pdf
+	const uint8_t pll_bypass = 1;
+	const uint8_t pll_bandselect = 0;
+	const uint8_t pll_outdiv = 0;
+	
+	uint8_t freq_div, freq_mult, last_freq_mult;  // mhz = (25 / freq_div * freq_mult)
+	float actual_mhz, last_actual_mhz = -1;
+	for (freq_div = 1; freq_div <= 32; ++freq_div)
+	{
+		freq_mult = mhz * freq_div / 25;
+		if (freq_mult > 0x80)
+			freq_mult = 0x80;
+		actual_mhz = 25. / freq_div * freq_mult;
+		if (last_actual_mhz > actual_mhz)
+		{
+			--freq_div;
+			freq_mult = last_freq_mult;
+			if (opt_debug)
+				actual_mhz = 25. / freq_div * freq_mult;
+			break;
+		}
+		if (actual_mhz > mhz - .5)
+			break;
+		last_actual_mhz = actual_mhz;
+		last_freq_mult = freq_mult;
+	}
+	const uint8_t pll_F = freq_mult - 1;
+	const uint8_t pll_R = freq_div - 1;
+	
+	const uint8_t core_clk_out1_diven = 0;
+	const uint8_t core_clk_sel1 = 0;
+	const uint8_t core_clk_sel0 = 0;
+	const uint8_t pll_clk_gate = 0;
+	const uint8_t pll_recfg = 1;
+	const uint8_t cfg_cpm = 1;
+	const uint32_t cfg = (pll_bypass << 31) | (pll_bandselect << 30) | (pll_outdiv << 28) | (pll_F << 21) | (pll_R << 16) | (core_clk_out1_diven << 6) | (core_clk_sel1 << 5) | (core_clk_sel0 << 4) | (pll_clk_gate << 3) | (pll_recfg << 2) | (cfg_cpm << 0);
+	gc3355_set_register(buf, 0xe, chipaddr, 0, cfg);
+}
+
+// NOTE: MHz must match CPM config
+static
+void gc3355_config_sha256d(uint8_t * const buf, const uint8_t chipaddr, const float mhz, const uint32_t baud)
+{
+	// See https://github.com/gridseed/gc3355-doc/blob/master/GC3355_Register_Spec.pdf
+	const uint8_t force_start = 1;
+	const uint8_t uart_enable = 1;
+	const uint8_t uart_debug = 0;
+	const uint8_t byte_order = 0;
+	const uint16_t rpt_cycle = (mhz * 1000000 / baud);
+	const uint32_t cfg = (force_start << 31) | (uart_enable << 30) | (uart_debug << 29) | (byte_order << 28) | rpt_cycle;
+	gc3355_set_register(buf, 0, chipaddr, 0xff, cfg);
+}
+
+static
+int gc3355_write(const int fd, const void * const buf, const size_t bufsz)
+{
+	const int rv = icarus_write(fd, buf, bufsz);
+	usleep(DEFAULT_DELAY_TIME);
+	return rv;
+}
+
 static
 void gc3355_send_cmds(int fd, const char *cmds[])
 {
@@ -378,88 +345,25 @@ void gc3355_opt_scrypt_init(int fd)
 static
 void gc3355_pll_freq_init2(int fd, int pll_freq)
 {
-	switch(pll_freq)
+	const uint8_t chipaddr = 0xf;
+	const uint32_t baud = 115200;  // FIXME: Make this configurable
+	uint8_t buf[8];
+	
+	if (!pll_freq)
 	{
-		case 400:
-		{
-			gc3355_send_cmds(fd, pll_freq_400M_cmd);
-			break;
-		}
-		case 500:
-		{
-			gc3355_send_cmds(fd, pll_freq_500M_cmd);
-			break;
-		}
-		case 550:
-		{
-			gc3355_send_cmds(fd, pll_freq_550M_cmd);
-			break;
-		}
-		case 600:
-		{
-			gc3355_send_cmds(fd, pll_freq_600M_cmd);
-			break;
-		}
-		case 650:
-		{
-			gc3355_send_cmds(fd, pll_freq_650M_cmd);
-			break;
-		}
-		case 700:
-		{
-			gc3355_send_cmds(fd, pll_freq_700M_cmd);
-			break;
-		}
-		case 750:
-		{
-			gc3355_send_cmds(fd, pll_freq_750M_cmd);
-			break;
-		}
-		case 800:
-		{
-			gc3355_send_cmds(fd, pll_freq_800M_cmd);
-			break;
-		}
-		case 850:
-		{
-			gc3355_send_cmds(fd, pll_freq_850M_cmd);
-			break;
-		}
-		case 900:
-		{
-			gc3355_send_cmds(fd, pll_freq_900M_cmd);
-			break;
-		}
-		case 950:
-		{
-			gc3355_send_cmds(fd, pll_freq_950M_cmd);
-			break;
-		}
-		case 1000:
-		{
-			gc3355_send_cmds(fd, pll_freq_1000M_cmd);
-			break;
-		}
-		case 1100:
-		{
-			gc3355_send_cmds(fd, pll_freq_1100M_cmd);
-			break;
-		}
-		case 1200:
-		{
-			gc3355_send_cmds(fd, pll_freq_1200M_cmd);
-			break;
-		}
-		default:
-		{
-			if (gc3355_get_cts_status(fd) == 1)
-				//1.2v - Scrypt mode
-				gc3355_send_cmds(fd, pll_freq_850M_cmd);
-			else
-				//0.9v - Scrypt + SHA mode
-				gc3355_send_cmds(fd, pll_freq_550M_cmd);
-		}
+		if (gc3355_get_cts_status(fd) == 1)
+			//1.2v - Scrypt mode
+			pll_freq = 850;
+		else
+			//0.9v - Scrypt + SHA mode
+			pll_freq = 550;
 	}
+	
+	gc3355_config_cpm(buf, chipaddr, pll_freq);
+	gc3355_write(fd, buf, sizeof(buf));
+	
+	gc3355_config_sha256d(buf, chipaddr, pll_freq, baud);
+	gc3355_write(fd, buf, sizeof(buf));
 }