To control a motor you need 2 gpios, A and B. You change the gpio levels to determine the motor state. E.g. A=B=0 stop, A=1 B=0 forward, A=0 B=1 backward, A=B=1 brake. You can change the speed by applying PWM to the gpio set to 1, i.e. you'd vary the forward speed by generating PWM on gpio A and the backward speed by generating PWM on gpio B.
The Pi has only one accessible dedicated PWM gpio.
However PWM is just rapidly switching a gpio on and off. The ratio of on to off determines the duty cycle. Always on is 100%, always off is 0%, half on/off is 50%. The more often you switch on and off the better (within limits). Arduinos (commonly used for this sort of application) use a switching rate of circa 500Hz.
You can use Linux to schedule the gpios on and off. This will suffer from jitter but is probably good enough for motor speed control.
A better method is to use one of the modules/libraries which use DMA to switch the gpios on and off. These allow jitter free and high Hz generation of PWM.
There are modules for Python and C.
I use my own C library, pigpio. See https://www.youtube.com/watch?v=2vq0Q4dD6KE