What's the point of buffering a peripheral
FIFO

FIFOs were in regular use in the late 1980's in UARTs. (I was using them regularly starting in 1989, for example.) The 16550 (and eventually the 16554 [quad UART]) made 16-byte FIFOs readily available. Given the processing speeds, interrupt latencies, and the increasing serial rates of the day it was very convenient and helpful.

The obvious benefit is that the interrupt (or polling) rate can be less frequent. If the overhead of events is expensive, lowering the frequency helps a great deal.

But there also are problems with using a FIFO (larger than 1 byte anyway.) The receive trigger level (these devices usually allowed some choices) means that the software doesn't examine any of the incoming data until that threshold is reached and an interrupt is triggered. Or, if the sender pauses for a while, the trigger threshold might never be reached. (This was handled sometimes by allowing a specified/documented worst-case delay -- often 4 character times -- and an interrupt would be triggered anyway if a delay like that occurred.) This can be bad for real-time systems or when processing packets and when the last fragment of a full packet is sitting in the FIFO with a long delay before the next packet is sent along. So there are trade-offs between better overall throughput and latency.

If the interrupt overhead isn't bad or if your data rates are slow enough it is probably simpler to do without the FIFO. Supporting a FIFO requires more code than not supporting one because the number of states and problems to worry about is increased.

DMA

This can be very helpful, at times. For example, in the SiLabs (was Cygnal) C8051F06x (which I made a lot of use of, since it is the only MCU sporting a decent 16-bit ADC, let alone one that runs at \$1\:\text{MHz}\$ conversion rates), you don't have any option in the matter if you want to support the maximum ADC conversion rate of \$1\:\text{MHz}\$. The C8051F06x uses an 8051 core with only one DPTR. And it is way, way too slow to keep up. Without the DMA, the ADC converter's capabilities would have been inaccessible and therefore wasted.

DMA is usually added because there is at least one peripheral in the family that either requires it or else would struggle hard without one. Once added, it can be relatively easy to enable the DMA unit itself to support more devices. If that is easy to do and not too difficult to document and support, it's likely to be enabled. (You may also see DMA supporting memory to memory transfers.)

Some DMA isn't just "programming a few registers and letting it fly." It can actually be a more sophisticated state machine all of its own that allows you to program it for different tasks. Again, I'll happily bring up the C8051F05x MCU. It's DMA requires some "programming" to operate. And the documentation (when I was messing with it) was completely inadequate. (Unusable, in fact, as it wasn't possible to correctly program it for the ADC without additional information that was missing.) I had to ask SiLabs, who took a few weeks to track down, locate, and then ask the original DMA designer (who had done the work 8 years before) -- then in Singapore, I think -- in order to get my questions answered.

Summary

Many ideas arrive when facing the problems caused when high data rates have to be supported. Hardware support, whether that is a FIFO or DMA or some other scheme, can be very helpful. Such solutions usually also come with their added problems (all swords are two-edged.) So there is a software and ongoing support price to pay in most cases. (And as in my case, delays due to having to track down a designer just to find out how to use it imply yet another kind of risk -- fewer people exist who know how something works and can help you and those attending delays in securing such help.) But usually it is worth paying, when a situation arises where you want a FIFO or DMA.