minion - ramp up the chip freq
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
diff --git a/ASIC-README b/ASIC-README
index 2e9ef1e..3e97c88 100644
--- a/ASIC-README
+++ b/ASIC-README
@@ -242,6 +242,8 @@ ASIC SPECIFIC COMMANDS
--klondike-options <arg> Set klondike options clock:temptarget
--minion-chipreport <arg> Seconds to report chip 5min hashrate, range 0-100 (default: 0=disabled)
--minion-freq <arg> Set minion chip frequencies in MHz, single value or comma list, range 100-1400 (default: 1200)
+--minion-freqchange Millisecond total time to do frequency changes (default: 1000)
+--minion-freqpercent Percentage to use when starting up a chip (default: 70%)
--minion-idlecount Report when IdleCount is >0 or changes
--minion-ledcount Turn off led when more than this many chips below the ledlimit (default: 0)
--minion-ledlimit Turn off led when chips GHs are below this (default: 90)
diff --git a/README b/README
index cc72853..3b6e36a 100644
--- a/README
+++ b/README
@@ -223,6 +223,8 @@ Options for both config file and command line:
--lowmem Minimise caching of shares for low memory applications
--minion-chipreport <arg> Seconds to report chip 5min hashrate, range 0-100 (default: 0=disabled)
--minion-freq <arg> Set minion chip frequencies in MHz, single value or comma list, range 100-1400 (default: 1200)
+--minion-freqchange Millisecond total time to do frequency changes (default: 1000)
+--minion-freqpercent Percentage to use when starting up a chip (default: 70%)
--minion-idlecount Report when IdleCount is >0 or changes
--minion-ledcount Turn off led when more than this many chips below the ledlimit (default: 0)
--minion-ledlimit Turn off led when chips GHs are below this (default: 90)
diff --git a/cgminer.c b/cgminer.c
index 734dacc..d62f237 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -256,6 +256,8 @@ static char *opt_set_null;
int opt_minion_chipreport;
char *opt_minion_cores;
char *opt_minion_freq;
+int opt_minion_freqchange = 1000;
+int opt_minion_freqpercent = 70;
bool opt_minion_idlecount;
int opt_minion_ledcount;
int opt_minion_ledlimit = 98;
@@ -1376,6 +1378,12 @@ static struct opt_table opt_config_table[] = {
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: 1200)"),
+ OPT_WITH_ARG("--minion-freqchange",
+ set_int_0_to_9999, opt_show_intval, &opt_minion_freqchange,
+ "Millisecond total time to do frequency changes (default: 1000)"),
+ OPT_WITH_ARG("--minion-freqpercent",
+ set_int_0_to_100, opt_show_intval, &opt_minion_freqpercent,
+ "Percentage to use when starting up a chip (default: 70%)"),
OPT_WITHOUT_ARG("--minion-idlecount",
opt_set_bool, &opt_minion_idlecount,
"Report when IdleCount is >0 or changes"),
diff --git a/driver-minion.c b/driver-minion.c
index 1e0bead..8ef8f4a 100644
--- a/driver-minion.c
+++ b/driver-minion.c
@@ -419,7 +419,6 @@ struct minion_status {
bool islow;
bool tohigh;
int lowcount;
- uint32_t freqsent;
uint32_t overheats;
struct timeval lastoverheat;
struct timeval lastrecover;
@@ -841,7 +840,6 @@ struct minion_info {
// TODO: need to track disabled chips - done?
int chips;
bool has_chip[MINION_CHIPS];
- int init_freq[MINION_CHIPS];
int init_temp[MINION_CHIPS];
uint8_t init_cores[MINION_CHIPS][DATA_SIZ*MINION_CORE_REPS];
@@ -976,6 +974,14 @@ struct minion_info {
bool lednow[MINION_CHIPS];
bool setled[MINION_CHIPS];
+ // When changing the frequency don't modify 'anything'
+ bool changing[MINION_CHIPS];
+ int init_freq[MINION_CHIPS];
+ int want_freq[MINION_CHIPS];
+ uint32_t freqsent[MINION_CHIPS];
+ struct timeval lastfreq[MINION_CHIPS];
+ int freqms[MINION_CHIPS];
+
bool initialised;
};
@@ -1482,8 +1488,9 @@ static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minionin
if (!minioninfo->xff_list->head)
show = true;
else {
- // xff_list is full
- if (minioninfo->xfree_list->count == 0) {
+ // if !changing and xff_list is full
+ if (!minioninfo->changing[obuf[0]] &&
+ minioninfo->xfree_list->count == 0) {
total = DATA_XFF(xitem)->when -
DATA_XFF(minioninfo->xff_list->tail)->when;
if (total <= MINION_POWER_TIME) {
@@ -1696,13 +1703,55 @@ static int build_cmd(struct cgpu_info *minioncgpu, struct minion_info *minioninf
return reply;
}
+static void set_freq(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int chip, int freq)
+{
+ uint8_t rbuf[MINION_BUFSIZ];
+ uint8_t data[4];
+ uint32_t value;
+ __maybe_unused int reply;
+
+ freq /= MINION_FREQ_FACTOR;
+ if (freq < MINION_FREQ_FACTOR_MIN)
+ freq = MINION_FREQ_FACTOR_MIN;
+ if (freq > MINION_FREQ_FACTOR_MAX)
+ freq = MINION_FREQ_FACTOR_MAX;
+ value = minion_freq[freq];
+ data[0] = (uint8_t)(value & 0xff);
+ data[1] = (uint8_t)(((value & 0xff00) >> 8) & 0xff);
+ data[2] = (uint8_t)(((value & 0xff0000) >> 16) & 0xff);
+ data[3] = (uint8_t)(((value & 0xff000000) >> 24) & 0xff);
+
+ minioninfo->freqsent[chip] = value;
+
+ reply = build_cmd(minioncgpu, minioninfo,
+ chip, WRITE_ADDR(MINION_SYS_FREQ_CTL),
+ rbuf, 0, data);
+
+ cgtime(&(minioninfo->lastfreq[chip]));
+
+ // Reset all this info on chip reset or freq change
+ minioninfo->reset_time[chip] = (int)FREQ_DELAY(minioninfo->init_freq[chip]);
+ if (second_check)
+ minioninfo->reset2_time[chip] = (int)FREQ2_DELAY(minioninfo->init_freq[chip]);
+
+ minioninfo->chip_status[chip].first_nonce.tv_sec = 0L;
+
+ // Discard chip history (if there is any)
+ if (minioninfo->hfree_list) {
+ K_WLOCK(minioninfo->hfree_list);
+ k_list_transfer_to_head(minioninfo->hchip_list[chip], minioninfo->hfree_list);
+ minioninfo->reset_mark[chip] = NULL;
+ minioninfo->reset_count[chip] = 0;
+ K_WUNLOCK(minioninfo->hfree_list);
+ }
+}
+
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;
@@ -1736,24 +1785,12 @@ static void init_chip(struct cgpu_info *minioncgpu, struct minion_info *minionin
// Set chip frequency
choice = minioninfo->init_freq[chip];
- if (choice < MINION_FREQ_MIN || choice > MINION_FREQ_MAX)
- choice = MINION_FREQ_DEF;
- choice /= MINION_FREQ_FACTOR;
- if (choice < MINION_FREQ_FACTOR_MIN)
- choice = MINION_FREQ_FACTOR_MIN;
- if (choice > MINION_FREQ_FACTOR_MAX)
- choice = MINION_FREQ_FACTOR_MAX;
- 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);
-
- minioninfo->chip_status[chip].freqsent = freq;
-
- reply = build_cmd(minioncgpu, minioninfo,
- chip, WRITE_ADDR(MINION_SYS_FREQ_CTL),
- rbuf, 0, data);
+ if (choice < MINION_FREQ_MIN)
+ choice = MINION_FREQ_MIN;
+ if (choice > MINION_FREQ_MAX)
+ choice = MINION_FREQ_MAX;
+ minioninfo->init_freq[chip] = choice;
+ set_freq(minioncgpu, minioninfo, chip, choice);
// Set temp threshold
choice = minioninfo->init_temp[chip];
@@ -1780,21 +1817,6 @@ static void init_chip(struct cgpu_info *minioncgpu, struct minion_info *minionin
reply = build_cmd(minioncgpu, minioninfo,
chip, WRITE_ADDR(MINION_SYS_TEMP_CTL),
rbuf, 0, data);
-
- // Discard chip history (if there is any)
- if (minioninfo->hfree_list) {
- K_WLOCK(minioninfo->hfree_list);
- k_list_transfer_to_head(minioninfo->hchip_list[chip], minioninfo->hfree_list);
- minioninfo->reset_mark[chip] = NULL;
- minioninfo->reset_count[chip] = 0;
- K_WUNLOCK(minioninfo->hfree_list);
- }
-
- minioninfo->reset_time[chip] = (int)FREQ_DELAY(minioninfo->init_freq[chip]);
- if (second_check)
- minioninfo->reset2_time[chip] = (int)FREQ2_DELAY(minioninfo->init_freq[chip]);
-
- minioninfo->chip_status[chip].first_nonce.tv_sec = 0L;
}
static void enable_chip_cores(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int chip)
@@ -2015,7 +2037,7 @@ static void minion_detect_one(struct cgpu_info *minioncgpu, struct minion_info *
static void minion_detect_chips(struct cgpu_info *minioncgpu, struct minion_info *minioninfo)
{
int pin, chipid, chip;
- int pinend;
+ int pinend, start_freq, want_freq, freqms;
if (usepins) {
init_pins(minioninfo);
@@ -2032,6 +2054,21 @@ static void minion_detect_chips(struct cgpu_info *minioncgpu, struct minion_info
if (minioninfo->chips) {
for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
if (minioninfo->has_chip[chip]) {
+ want_freq = minioninfo->init_freq[chip];
+ start_freq = want_freq * opt_minion_freqpercent / 100;
+ start_freq -= (start_freq % MINION_FREQ_FACTOR);
+ if (start_freq < MINION_FREQ_MIN)
+ start_freq = MINION_FREQ_MIN;
+ minioninfo->want_freq[chip] = want_freq;
+ minioninfo->init_freq[chip] = start_freq;
+ if (start_freq != want_freq) {
+ minioninfo->changing[chip] = true;
+ freqms = opt_minion_freqchange;
+ freqms /= ((want_freq - start_freq) / MINION_FREQ_FACTOR);
+ if (freqms < 0)
+ freqms = -freqms;
+ minioninfo->freqms[chip] = freqms;
+ }
init_chip(minioncgpu, minioninfo, chip);
enable_chip_cores(minioncgpu, minioninfo, chip);
}
@@ -3216,6 +3253,29 @@ static void *minion_spi_reply(void *userdata)
if (minioninfo->has_chip[chip]) {
int tries = 0;
uint8_t res, cmd;
+
+ if (minioninfo->changing[chip] &&
+ ms_tdiff(&now, &minioninfo->lastfreq[chip]) >
+ minioninfo->freqms[chip]) {
+ int want_freq = minioninfo->want_freq[chip];
+ int init_freq = minioninfo->init_freq[chip];
+
+ if (want_freq > init_freq) {
+ minioninfo->init_freq[chip] += MINION_FREQ_FACTOR;
+ init_freq += MINION_FREQ_FACTOR;
+
+ set_freq(minioncgpu, minioninfo, chip, init_freq);
+ } else if (want_freq < init_freq) {
+ minioninfo->init_freq[chip] -= MINION_FREQ_FACTOR;
+ init_freq -= MINION_FREQ_FACTOR;
+
+ set_freq(minioncgpu, minioninfo, chip, init_freq);
+ }
+
+ if (init_freq == want_freq)
+ minioninfo->changing[chip] = false;
+ }
+
while (++tries < 4) {
res = cmd = 0;
fifo_task.chip = chip;
@@ -3641,7 +3701,7 @@ static enum nonce_state oknonce(struct thr_info *thr, struct cgpu_info *minioncg
struct timeval now;
K_ITEM *item, *tail;
uint32_t min_task_id, max_task_id;
- uint64_t chip_good;
+// uint64_t chip_good;
bool redo;
// if the chip has been disabled - but we don't do that - so not possible (yet)
@@ -3757,7 +3817,7 @@ retest:
if (redo)
minioninfo->nonces_recovered[chip]++;
- chip_good = ++(minioninfo->chip_good[chip]);
+ /* chip_good = */ ++(minioninfo->chip_good[chip]);
minioninfo->chip_status[chip].from_first_good++;
minioninfo->core_good[chip][core]++;
DATA_WORK(item)->nonces++;
@@ -3823,11 +3883,13 @@ retest:
}
K_WUNLOCK(minioninfo->hfree_list);
+/*
// Reset the chip after 8 nonces found
if (chip_good == 8) {
memcpy(&(minioninfo->last_reset[chip]), &now, sizeof(now));
init_chip(minioncgpu, minioninfo, chip);
}
+*/
return NONCE_GOOD_NONCE;
}
@@ -4640,6 +4702,10 @@ static void chip_report(struct cgpu_info *minioncgpu)
}
}
+ // Don't reset the chip while 'changing'
+ if (minioninfo->changing[chip])
+ return;
+
msdiff = ms_tdiff(&now, &(minioninfo->chip_chk));
if (total_secs >= MINION_RESET_s && msdiff >= (minioninfo->history_gen * 1000)) {
K_RLOCK(minioninfo->hfree_list);
@@ -4887,7 +4953,7 @@ static struct api_data *minion_api_stats(struct cgpu_info *minioncgpu)
snprintf(buf, sizeof(buf), "Chip %d InitFreq", chip);
root = api_add_int(root, buf, &(minioninfo->init_freq[chip]), true);
snprintf(buf, sizeof(buf), "Chip %d FreqSent", chip);
- root = api_add_hex32(root, buf, &(minioninfo->chip_status[chip].freqsent), true);
+ root = api_add_hex32(root, buf, &(minioninfo->freqsent[chip]), true);
snprintf(buf, sizeof(buf), "Chip %d InitTemp", chip);
temp = minioninfo->init_temp[chip];
if (temp == MINION_TEMP_CTL_DISABLE)
diff --git a/miner.h b/miner.h
index 94e44f0..1cab4a8 100644
--- a/miner.h
+++ b/miner.h
@@ -1025,6 +1025,8 @@ extern bool opt_bitmain_tempoverctrl;
extern int opt_minion_chipreport;
extern char *opt_minion_cores;
extern char *opt_minion_freq;
+extern int opt_minion_freqchange;
+extern int opt_minion_freqpercent;
extern bool opt_minion_idlecount;
extern int opt_minion_ledcount;
extern int opt_minion_ledlimit;