Documentation of GPIOs in Linux states:
A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
digital signal. They are provided from many kinds of chip, and are familiar
to Linux developers working with embedded and custom hardware.
When you design an integrated circuit (chip) you design with some component model in mind, those internal components may have specific needs that can not be reassigned among different pins, then those pins are fixed function.
For example pins related to memory controller have a very strict performance requirements set (in terms of signal integrity, toggle rate, output driver, capacitance), those pins are fixed function not reassignable, thus you can not use those pins for GPIO. If you do it you will end with a slower chip because the additional circuit change those values becoming unfeasible. Other example are power domain pins (those tipically called VCC, VDD, VEE, GND,).
Thats why GPIO pins are always shared with slow interfaces like SPI, I2C, SMBUS but never with fast interfaces like SATA, DDR, etc.
In other cases the only reason is because the chip doesnt make sense without a particular component, for example, given you must to have RAM memory, then RAM dedicated pins doesnt need to be reassignable because you never will implement the system without RAM memory and never will need reuse those pins for GPIO