Since commit 3d4217bf there is now support for host-driven power management to transition between operational power states. It works by having IOKit notify us about (lack of) controller activity within certain time intervals. This should integrate transparently with PCI link power management and APST. I'm not entirely sure which timer interval is useful; you may experiment with it here https://github.com/acidanthera/NVMeFix/blob/master/NVMeFix/nvme_pm.cpp#L109 (in seconds). This is still not as advanced as power management for Apple controllers: they implement Quality of Service, where clients indicate the expected workloads and operation priorities, and power state is selected accordingly.
You may check the supported power states yourself by using smartmontools. For example, for my controller, it reports
the following states:
Supported Power States
St Op Max Active Idle RL RT WL WT Ent_Lat Ex_Lat
0 + 9.00W - - 0 0 0 0 0 0
1 + 4.60W - - 1 1 1 1 0 0
2 + 3.80W - - 2 2 2 2 0 0
3 - 0.0450W - - 3 3 3 3 2000 2000
4 - 0.0040W - - 4 4 4 4 6000 8000
NVMeFix then uses the first three states for host-driven power management, and latter, non-operational states, are used for APST. IOPower:/IOPowerConnection/IOPMrootDomain/IOPowerConnection/NVMePMProxy IOPowerManagement dictionary will report four power states possible: state 0 corresponds to power off state and should not be reachable; state 1 corresponds to state 2 in the above report etc.