Browse Source

aan: Logic to calculate PLL configurations for a given frequency

Luke Dashjr 11 years ago
parent
commit
4659b7ffff
2 changed files with 87 additions and 0 deletions
  1. 83 0
      driver-aan.c
  2. 4 0
      miner.c

+ 83 - 0
driver-aan.c

@@ -23,6 +23,9 @@
 
 
 #define AAN_DEFAULT_NONCE_PDIFF  8
 #define AAN_DEFAULT_NONCE_PDIFF  8
 
 
+// WARNING: Do not just change this without fixing aan_freq2pll!
+#define AAN_MAX_FREQ  6132
+
 #define AAN_PROBE_TIMEOUT_US  3750000
 #define AAN_PROBE_TIMEOUT_US  3750000
 #define AAN_INIT_TIMEOUT_US   5000000
 #define AAN_INIT_TIMEOUT_US   5000000
 #define AAN_READ_INTERVAL_US   100000
 #define AAN_READ_INTERVAL_US   100000
@@ -40,6 +43,86 @@ enum aan_cmd {
 	AAN_READ_REG_RESP        = 0x1a,
 	AAN_READ_REG_RESP        = 0x1a,
 };
 };
 
 
+static
+unsigned aan_pll2freq(const uint16_t pll)
+{
+	const uint8_t pll_postdiv = (pll >> 0xe);
+	const uint8_t pll_prediv = (pll >> 9) & 0x1f;
+	const uint16_t pll_fbdiv = pll & 0x1ff;
+	return (12 * pll_fbdiv) / pll_prediv / (1 << (pll_postdiv - 1));
+}
+
+static
+uint16_t aan_freq2pll(unsigned freq)
+{
+retry: ;
+	uint8_t postdiv = 3, prediv = 3;
+	uint16_t fbdiv = freq / 3;
+	if (fbdiv * 3 == freq)
+		prediv = 1;
+	else
+		fbdiv = freq;
+	if (!(fbdiv & 3))
+	{
+		fbdiv >>= 2;
+		postdiv = 1;
+	}
+	else
+	if (!(fbdiv & 1))
+	{
+		fbdiv >>= 1;
+		postdiv = 2;
+	}
+	if (fbdiv > 0x1ff)
+	{
+		--freq;
+		goto retry;
+	}
+	const uint16_t pll = (((postdiv << 5) | prediv) << 9) | fbdiv;
+	return pll;
+}
+
+static
+void _test_aan_pll(const unsigned expect, const uint8_t postdiv, const uint8_t prediv, const uint16_t fbdiv)
+{
+	const uint16_t pll = (((postdiv << 5) | prediv) << 9) | fbdiv;
+	const unsigned got = aan_pll2freq(pll);
+	if (got != expect)
+		applog(LOG_WARNING, "%s test failed for %4u(%x,%02x,%3d): got %4u", "aan_pll2freq", expect, postdiv, prediv, fbdiv, got);
+}
+
+static
+void _test_aan_pll2(const unsigned freq)
+{
+	const uint16_t pll = aan_freq2pll(freq);
+	const unsigned got = aan_pll2freq(pll);
+	if (got / 12 != freq / 12)
+	{
+		const uint8_t postdiv = (pll >> 0xe);
+		const uint8_t prediv = (pll >> 9) & 0x1f;
+		const uint16_t fbdiv = pll & 0x1ff;
+		applog(LOG_WARNING, "%s test failed for %4u: got %4u(%x,%02x,%3d)", "aan_freq2pll", freq, got, postdiv, prediv, fbdiv);
+	}
+}
+
+void test_aan_pll(void)
+{
+	_test_aan_pll(1000, 0b01,0b00011,0b011111010);
+	_test_aan_pll( 950, 0b10,0b00011,0b111011011);
+	_test_aan_pll( 900, 0b01,0b00001,0b001001011);
+	_test_aan_pll( 850, 0b10,0b00011,0b110101001);
+	_test_aan_pll( 800, 0b01,0b00011,0b011001000);
+	_test_aan_pll( 750, 0b10,0b00001,0b001111101);
+	_test_aan_pll( 700, 0b01,0b00011,0b010101111);
+	_test_aan_pll( 650, 0b10,0b00011,0b101000101);
+	_test_aan_pll( 600, 0b01,0b00001,0b000110010);
+	_test_aan_pll( 550, 0b10,0b00011,0b100010011);
+	_test_aan_pll( 500, 0b10,0b00011,0b011111010);
+	_test_aan_pll( 100, 0b11,0b00011,0b001100100);
+	for (unsigned i = 1; i <= AAN_MAX_FREQ; ++i)
+		_test_aan_pll2(i);
+}
+
 static void aan_spi_parse_rx(struct spi_port *);
 static void aan_spi_parse_rx(struct spi_port *);
 
 
 static
 static

+ 4 - 0
miner.c

@@ -11801,6 +11801,7 @@ static void raise_fd_limits(void)
 
 
 extern void bfg_init_threadlocal();
 extern void bfg_init_threadlocal();
 extern void stratumsrv_start();
 extern void stratumsrv_start();
+extern void test_aan_pll(void);
 
 
 int main(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
 {
@@ -12049,6 +12050,9 @@ int main(int argc, char *argv[])
 		test_target();
 		test_target();
 		test_uri_get_param();
 		test_uri_get_param();
 		utf8_test();
 		utf8_test();
+#ifdef USE_JINGTIAN
+		test_aan_pll();
+#endif
 	}
 	}
 
 
 #ifdef HAVE_CURSES
 #ifdef HAVE_CURSES