Millis uses Timer0 (like basically all AVR parts - I don't think I have ever seen an example of this!). This also drives two PWM channels.
As long as you do not manipulate the timer0 registers directly (for example, to change the frequency), millis() will work.
If you do need to manipulate the timer0 registers to change the frequency - particularly if you want to increase it significantly (which it appears that you do), you should disable millis entirely. At prescale of 1 instead of 64, with millis enabled, the CPU is spending something like 40% (very rough estimate - I have not timed the classic AVRs. That data is extrapolated from the tinyAVR 0/1-series supported by megaTinyCore) of it's time in the millis ISR!
With millis disabled, delay() and delayMicroseconds() still work (slightly less accurately - delay gets changed from the normal implementation, which allows other interrupts to fire and calls yield(), to just calling delayMicroseconds(1000) (which turns off interrupts and counts clock cycles) for every millisecond).
If you're looking for something that size, but with 4 PWM channels you can play with without trashing millis, there are two options:
- The ATtiny841 - the real crown jewel of the classic tinyAVR line, IMHO, which has TWO of those nice 16-bit timers (plus the 8-bit one) - timer 1 and 2 on the '841 work like timer1 on the '84. It also has dual hardware serial ports! What's really nice about the '841 is that not only do you get 4 channels, but you get an independent prescaler for each timer, and the full 16-bits of resolution
- A modern AVR from the tinyAVR 0/1-series. They all have 6 PWM pins driven by TCA0 (core configures it in split mode as 2 8-bit timers with 3 channels). You can also move the millis timer around with a tools submenu to make sure it's not using TCA0. All the tinyAVR 0/1-series can do 20MHz @ 5v w/out crystal (and more accurate frequency than the classics), have 1 serial port, SPI, and I2C. 14 pin parts have up to 16k flash, and 20/24 pin parts have up to 32k. See GitHub - SpenceKonde/megaTinyCore: Arduino core for the tinyAVR 0/1/2-series - this is any ATtiny part where hundreds and thousands place is 2 or more (flash size in kb), the ones place is a 2, 4, 6, or 7 (8. 14. 20 or 24 pins) and the tens place is a 0, 1, or 2 (featureset)/ The downside, though, is that you have to relearn how to control the peripherals - they're very different. Better, but way different.
(and, naturally, I have breakout boards for those, assembled or bare, in my Tindie store )
As an aside, if you're planning to use that PWM to switch a MOSFET, you probably need a gate driver on it - the relatively weak drivers on an microcontroller I/O pin are not able to switch a FET on/off as quickly as one might want (see "gate charge", "gate capacitance"), so switching losses (from the time the FET is half-on durign the transitions, and hence conducting, but at higher resistance) increase, leading to your fet getting far hotter than you would expect. More of a problem with big FETs, as they have higher gate capacitance (so slower switching) and are presumably carrying a heavier load, hence a half-on FET will generate more heat. I do happen to sell MOSFET boards with beefy MOSFETs and gate drivers if you really need high current PWM at high frequencies - gate drivers are designed to switch with low input current at logic levels while supplying a brief pulse of high current into the gate to slam it on or off quickly.
I only know of one AVR for which cores have been in circulation that didn't use timer0 for millis. Some old '85 cores used timer1 instead. The "logic" if you can call it that, was that timer1 on the '85 is weird (it's a wacky "high speed" timer than can be clocked at 64MHz from the on-chip PLL, among other things), and they assumed nobody would know how to program it, since it's unique to the '85.... but nobody knows the 8-bit timer0 off-hand either, because on every other AVR with arduino support, it's used for millis! And the high-speed timer1 is like, one of the headline features of the '85....